Spring jdbcTemaplate как отправить полный размер партии на сервер DB2 за один снимок?

Пока выполняется jdbcTemplate.batchUpdate(...), я вижу, что количество строк в db увеличивается постепенно (путем запуска count (*) в таблице), изначально 2k, затем 3k и до 10k. 2k и 3k не являются точными числами, иногда я получаю 2357, а затем 4567.

Я ожидал, что 10 k строк (размер партии) будут зафиксированы за один снимок. В моем понимании, если изначально я получаю число строк 0, то следующее количество строк должно быть 10k. Я не хочу, чтобы одна за другой вставляла по соображениям производительности, почему использование функции batchupdate и, похоже, также не делает все за один снимок.

Я хочу отправить данные (строки 10k) на сервер DB только один раз для моего batchsize. для этого есть что-нибудь, что я должен указать в конфигурации?

Ниже приводится способ публикации пакетного обновления jdbcTemplate. batchsize - 10k.

public void insertRows(...) { 
    ... 
    jdbcTemplate.batchUpdate(query, new BatchPreparedStatementSetter(){
    @Override public void

    setValues(PreparedStatement ps, int i) throws SQLException {
        ... 
    }

    @Override public int getBatchSize() { 
        if(data == null){ 
            return 0; 
        }
        return data.size(); 
    }
   }); 
}

Изменить: Добавлено @Transactional в метод isertRows stiil, я вижу такое же поведение. используя Transnational, он фиксируется после строк 10k, но когда я вижу счет, используя UR (выберите count (*) из mytable с ur), он показывает, что данные обновляются постепенно (2k 4k и далее до 10k). Это означает, что данные поступают на сервер в кусках (возможно, один за другим). Как я могу отправить все за один выстрел. Этот вопрос предполагает, что он достигается с помощью rewriteBatchedStatements в mysql, есть ли что-то подобное в DB2, а также.

Я использую реализацию DataSource com.ibm.db2.jcc.DB2BaseDataSource

Ответ 1

Как насчет метода ниже? укажите nUpdates = 10 000 в вашем случае. Я не пробовал тестировать this.please игнорировать мой ответ, если он не работает.

// the batch size is set in the BatchPreparedStatementSetter, the number of rows we want to process is equal to the nbUpdates parameter
    public int[] batchUpdate(String sql, final long nbUpdates, final BatchPreparedStatementSetter pss) throws DataAccessException {
        if (logger.isDebugEnabled()) {
            logger.debug("Executing SQL batch update [" + sql + "]");
        }

        return (int[]) execute(sql, new PreparedStatementCallback() {
            public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
                try {
                    int batchSize = pss.getBatchSize();
                    InterruptibleBatchPreparedStatementSetter ipss = (pss instanceof InterruptibleBatchPreparedStatementSetter ? (InterruptibleBatchPreparedStatementSetter) pss
                            : null);
                    if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
                        List<Integer> rowsAffected = new ArrayList<Integer>();
                        for (int i = 1; i <= nbUpdates; i++) {
                            pss.setValues(ps, i - 1);
                            if (ipss != null && ipss.isBatchExhausted(i - 1)) {
                                if (logger.isDebugEnabled()) {
                                    int batchIdx = (i % batchSize == 0) ? i / batchSize : (i / batchSize) + 1;
                                    logger.debug("Batch exhausted - Sending last SQL batch update #" + batchIdx);
                                }
                                int[] res = ps.executeBatch();
                                for (int j = 0; j < res.length; j++) {
                                    rowsAffected.add(res[j]);
                                }
                                break;
                            }
                            ps.addBatch();
                            if (i % batchSize == 0 || i == nbUpdates) {
                                if (logger.isDebugEnabled()) {
                                    int batchIdx = (i % batchSize == 0) ? i / batchSize : (i / batchSize) + 1;
                                    logger.debug("Sending SQL batch update #" + batchIdx);
                                }
                                int[] res = ps.executeBatch();
                                for (int j = 0; j < res.length; j++) {
                                    rowsAffected.add(res[j]);
                                }
                            }
                        }
                        int[] result = new int[rowsAffected.size()];
                        for (int i = 0; i < result.length; i++) {
                            result[i] = rowsAffected.get(i).intValue();
                        }
                        return result;
                    } else {
                        List<Integer> rowsAffected = new ArrayList<Integer>();
                        for (int i = 0; i < nbUpdates; i++) {
                            pss.setValues(ps, i);
                            if (ipss != null && ipss.isBatchExhausted(i)) {
                                break;
                            }
                            rowsAffected.add(ps.executeUpdate());
                        }
                        int[] rowsAffectedArray = new int[rowsAffected.size()];
                        for (int i = 0; i < rowsAffectedArray.length; i++) {
                            rowsAffectedArray[i] = rowsAffected.get(i);
                        }
                        return rowsAffectedArray;
                    }
                } finally {
                    if (pss instanceof ParameterDisposer) {
                        ((ParameterDisposer) pss).cleanupParameters();
                    }
                }
            }
        });
    }