虽然jdbcTemplate.batchUpdate(…)正在运行我可以看到db行计数逐渐增加(通过在表中运行count(*)),最初是2k然后3k并且直到10k. 2k和3k不是精确的数字有时我得到2357然后4567.
我期待10 k行(批量大小)一次性提交.在我的理解,如果最初我得到行计数0,那么下一行计数应该是10k.
我不想一个接一个插入性能的原因,这就是为什么使用batchupdate功能,似乎也没有提交一个镜头.
我想要发送数据(10k行)到DB服务器只有一次我的批量大小.为什么我应该在配置中指定什么?
下面是我编写jdbcTemplate批处理更新的方式.批量大小是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我可以看到相同的行为.
使用跨国它在10k行后提交,但是当我看到使用UR的计数(从url中选择count(*))表示数据逐渐更新(2k 4k等到10k).这意味着数据以大块(大概是一个一个)到服务器.我怎么能一次性发送一切. This question建议在MysqL中使用rewriteBatchedStatements来实现,还有与DB2类似的东西.
我正在使用DataSource实现com.ibm.db2.jcc.DB2BaseDataSource
解决方法
下面的方法怎么样?在你的情况下指定nUpdates = 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(); } } } }); }