mysql jdbc不成功回滚

时间:2012-11-07 12:17:34

标签: java mysql jdbc rollback autocommit

我有一些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;"

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

我正在使用MySQL版本'5.0.91-community-nt'。 MySQL jdbc驱动程序版本是5.1.19。我正在使用Java 5.

有没有人有任何关于为什么我的更新被提交的建议,即使自动提交已关闭,也从未调用提交,并且显式调用了回滚?

干杯。

1 个答案:

答案 0 :(得分:2)

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

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