【问题标题】:Does ResultSet.updateRow() commit, i.e. end the transaction?ResultSet.updateRow() 是否提交,即结束事务?
【发布时间】:2020-01-03 21:06:42
【问题描述】:

根据文档ResultSet.updateRow()Updates the underlying database with the new contents of the current row of this ResultSet object.

这是否会执行提交,即结束当前事务?

【问题讨论】:

  • 该方法应该像更新查询一样更新数据库,即如果数据库和连接未设置为自动提交,则事务应该仍然存在。

标签: java jdbc transactions commit


【解决方案1】:

如果禁用自动提交,那么只有显式调用Connection.commit() 才会提交事务。因此,禁用自动提交后,将不会提交更新结果集行。

启用自动提交模式后,将应用不同的规则。 JDBC 4.3 specification,第 10.1 节 事务边界和自动提交 说:

Connection 属性 auto-commit 指定何时结束 交易。启用自动提交后会导致事务提交 一旦该语句完成,每个单独的 SQL 语句。 一个陈述被认为是“完整”的点取决于 关于 SQL 语句的类型以及应用程序的功能 执行后:

  • 对于数据操作语言 (DML) 语句,例如 Insert、Update、Delete 和 DDL 语句,语句会尽快完成 因为它已完成执行。
  • 对于Select 语句,当关联的结果集关闭时,语句就完成了。
  • 对于CallableStatement 对象或返回多个结果的语句,当所有关联的 结果集已关闭,所有更新计数和输出 已检索参数。

由于更新结果集中的行不会关闭结果集,因此它不会完成语句,因此它应该触发提交。因此,根据 JDBC 标准,在自动提交模式下更新结果集中的行不应该在结果集关闭之前提交。

但是,实际实现完全有可能不遵守此规则。例如,因为驱动程序使用UPDATE 语句来实现更改,并且驱动程序使用服务器端自动提交逻辑,一旦UPDATE 语句结束,它将自动提交。另外,鉴于我引用的规则有点含糊,驱动程序还可以解释行的更新是 DML 更新的规则,因此应该触发提交。

换句话说,自动提交模式和可更新的结果集在不同的 JDBC 驱动程序之间可能表现不同。我建议当您想使用可更新的结果集时,禁用自动提交模式,以便您的代码通过显式调用 Connection.commit() 来控制事务边界。

顺便说一句,使用可更新的结果集几乎总是错误的工具。如果您真的需要使用它们,请仔细考虑。它们仅在交互式用户应用程序中才真正有意义,即便如此,您也应该考虑替代方案。

【讨论】:

    猜你喜欢
    • 2015-03-19
    • 2016-08-30
    • 2021-12-13
    • 1970-01-01
    • 1970-01-01
    • 2015-08-04
    • 1970-01-01
    • 2017-09-14
    • 1970-01-01
    相关资源
    最近更新 更多