【问题标题】:does my batch really execute as expected if autocommit is set to true? [duplicate]如果自动提交设置为 true,我的批处理是否真的按预期执行? [复制]
【发布时间】:2014-11-12 13:57:19
【问题描述】:

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

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

do I need a connection.commit() after executeBatch()?

代码是:

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

}

【问题讨论】:

    标签: java jdbc transactions prepared-statement


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      好像是every statement in the batch is executed separately。否则会猜到的。许多教程建议在批处理之前设置setAutoCommit(false),以便在一个步骤失败时能够回滚整个批处理。参见例如http://www.jguru.com/faq/view.jsp?EID=5079 声明:

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

      这个论证隐含地确认,当启用自动提交时,每条语句都是由自己提交的。

      【讨论】:

      • 非常感谢安德烈!
      • cc: @stackSaru - re: “批处理中的每个语句都是单独执行的” - 至少有一种情况不完全正确:如果 MySQL 连接器/J 连接字符串包括 rewriteBatchedStatements=true 和一系列单独的单行 INSERT INTO ... VALUES ... 语句被添加到 PreparedStatement 的批处理中,然后 MySQL JDBC 驱动程序会将多个单行 INSERT 重写为一个或多个多行 INSERT当批处理执行时。详情见相关问题here
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-04
      • 1970-01-01
      • 2019-03-01
      • 1970-01-01
      相关资源
      最近更新 更多