Spring jdbcTemaplate 如何一次性将完整的批大小发送到 DB2 服务器?

2022-09-04 23:38:42

当jdbcTemplate.batchUpdate(...)运行时,我可以看到DB行数逐渐增加(通过在表中运行),最初是2k,然后是3k,直到10k。count(*)

我期望一次提交10 k行(批量大小)。在我的理解中,如果最初,我得到行计数0,那么下一行计数应该是10k。出于性能原因,我不想要一个接一个地插入,这就是为什么使用批量更新功能,似乎它也不能一次性提交所有内容。

对于我的批大小,我只想向数据库服务器发送一次数据(10k行)。为此,我应该在配置中指定任何内容吗?

以下是我编写批量更新的方式,批量大小为10k。jdbcTemplate

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 方法中,我仍然可以看到相同的行为。使用跨国它在10k行之后提交,但是当我看到与UR一起使用的计数(从mytable中选择count(*)与你的)时,它显示数据逐渐更新(2k 4k依此类推,直到10k)。这意味着数据以块的形式进入服务器(可能是一个再见)。我怎么能一次性发送所有内容。这个问题表明它是在 mysql 中使用 rewriteBatchedStatements 实现的,我们在 DB2 中也有类似的东西吗?

我正在使用DataSource implementation com.ibm.db2.jcc.DB2BaseDataSource


答案 1

以下方法怎么样?在您的案例中指定 nUpdate = 10,000。我没有尝试过测试这个。如果它不起作用,请忽略我的答案。

// 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();
                    }
                }
            }
        });
    }

答案 2

推荐