ResultSet.updateRow() 是否提交,即结束交易?

Does ResultSet.updateRow() commit, i.e. end the transaction?

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

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

如果禁用自动提交,则只有显式调用 Connection.commit() 才会提交事务。因此,在禁用自动提交的情况下,更新结果集行将不会提交。

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

The Connection attribute auto-commit specifies when to end transactions. Enabling auto-commit causes a transaction commit after each individual SQL statement as soon as that statement is complete. The point at which a statement is considered to be “complete” depends on the type of SQL statement as well as what the application does after executing it:

  • For Data Manipulation Language (DML) statements such as Insert, Update, Delete, and DDL statements, the statement is complete as soon as it has finished executing.
  • For Select statements, the statement is complete when the associated result set is closed.
  • For CallableStatement objects or for statements that return multiple results, the statement is complete when all of the associated result sets have been closed, and all update counts and output parameters have been retrieved.

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

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

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

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