4

我有一些 Java 代码使用 JDBC 连接到 MySQL 数据库,然后代码执行一些读取操作,然后进行一次更新,所有这些都使用相同的连接。如果有异常,则connection.rollback()调用;如果没有异常,connection.commit()则调用。在这个阶段,每次我运行测试时都会新创建连接(即它不是来自池)。我的代码只创建一个连接,并在整个测试过程中使用。

正在使用connection.setAutoCommit(false)的连接在连接实例创建后立即调用。

由于某种原因,当出现异常并被connection.rollback()调用时,事实证明我的更新已提交而不是回滚。

通过调试,我确认了以下内容,

  • 调用后connection.setAutoCommit(false),按预期connection.getAutoCommit()返回 的值。false此外,"Select @@session.autocommit"返回值0,表示自动提交已按预期关闭。

  • 在调用 之前connection.rollback(),同样的检查显示自动提交已关闭,正如预期的那样。

  • connection.commit()绝对没有被调用,并且connection.rollback()肯定被调用。

我也尝试过显式运行该语句"rollback;",但它并没有解决我的问题。我还尝试"Set AUTOCOMMIT = 0;"在创建连接后显式运行该语句。

我所有的表都使用 InnoDB 的存储引擎。通过 SQL Workbench,自动提交关闭,回滚和提交按预期工作。

我正在使用 MySQL 版本“5.0.91-community-nt”。MySQL jdbc 驱动版本为 5.1.19。我正在使用 Java 5。

有没有人对为什么我的更新被提交有任何建议,即使自动提交关闭,提交从未被调用,并且回滚被明确调用?

干杯。

4

1 回答 1

2

我在 OP 中引用的代码不在单个块中,而是分散在各个类中。为了满足上面对代码示例的查询,我准备了一个代码块来说明问题。代码块完成后,我对其进行了测试以确保可以复制该问题。好吧,我无法复制这个问题 - 回滚工作得很好。这导致我通过生产代码来计算它在我放在一起的代码块之外所做的所有事情。

事实证明,生产代码既创建又删除临时表。最相关的是,它在执行更新后删除临时表,并且无论是否存在异常都会删除临时表。事实证明,在 MySQL 中删除表会引发隐式提交调用。因此,在我的代码抛出异常和我的代码调用 connection.rollback() 之间,它会删除导致隐式调用提交的表。因此我的“自动提交”问题。

于 2012-11-07T13:53:43.750 回答