如果自动提交设置为 true,我的批处理是否真的按预期执行?

sta*_*aru 5 java transactions jdbc prepared-statement

我正在发出请求 SQL 来提交一些更新。更新已完成且良好,但我想知道批处理是否正确执行,即语句是一次性提交的还是语句一个接一个地执行?这是因为自动提交被隐式设置为 true,我想知道为了使批处理作为真正的“批处理”执行,我是否必须将其设置为 false。

这是一个与此相关的问题:

在executeBatch()之后我需要一个connection.commit()吗?

代码是:

private void pdate(JdbcTemplate jdbcTemplate, List<Long> saisineIdsToUpdate,Connection connection) throws SQLException {
   String sqlUpdate = "UPDATE SAISINES SAI WHERE SAI.IDSAISINE = ?"; //request simplified

   PreparedStatement psUpdate = connection.prepareStatement(sqlUpdate);

   for (Long saisineId : saisineIdsToUpdate) {
      psUpdate.setLong(1, saisineId );
      psUpdate.addBatch();
   }

   psUpdate.executeBatch();
   psUpdate.close();

}
Run Code Online (Sandbox Code Playgroud)

Mar*_*eel 5

根据 JDBC 规范,自动提交下的批处理执行行为是特定于实现的。也就是说:当自动提交为 true 时,批次是单个事务还是每个项目的事务由驱动程序(或数据库)决定。错误是回滚所有内容还是仅回滚自动提交下的该项目,这也是特定于实现的。

这就是为什么通常建议在使用批量执行时禁用自动提交并自己显式提交(或回滚)。


And*_*nek 1

看起来批处理中的每个语句都是单独执行的。否则的话会猜到的。许多教程建议setAutoCommit(false)在一批之前进行设置,以便在一个步骤失败时能够回滚整个批次。请参阅http://www.jguru.com/faq/view.jsp?EID=5079,其中指出:

在执行批量更新之前,通过调用 setAutoCommit(false) 禁用自动提交模式非常重要。这样,如果其中一个更新因任何原因失败,您将能够回滚批处理事务。

此论证隐含地确认,当启用自动提交时,每个语句都会自行提交。

  • 抄送:@stackSaru - 回复:*“批处理中的每个语句都单独执行”* - 至少有一种情况不完全正确:如果 MySQL Connector/J 连接字符串包含 `rewriteBatchedStatements=true` 和一系列将单个单行“INSERT INTO ... VALUES ...”语句添加到一批PreparedStatement中,然后当该批处理时,MySQL JDBC驱动程序将多个单行INSERT重写为一个或多个多行INSERT被执行。有关详细信息,请参阅[此处](http://stackoverflow.com/q/26307760/2144390)的相关问题。 (4认同)