java - mysql jdbc 不成功回滚

标签 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;" 但它没有解决我的问题。我还尝试在创建连接后显式运行语句 "Set AUTOCOMMIT = 0;"

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

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

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

干杯。

最佳答案

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

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

关于java - mysql jdbc 不成功回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13269632/

相关文章:

java - 在java中创建一个堆栈

java - jdbcTemplate执行完查询后如何在Spring Boot中关闭连接?

mysql - 无法在 Apache Drill 中创建新的 mysql 存储

java - 错误的 TLS 版本

java - 为什么这个程序的输出是-1?

mysql - XAMPP——Apache 和 MySQL

mysql - 撤消 mysql UPDATE 命令

mysql - 我如何使用 select 语句

java - 应该如何从 Spring Data Neo4j 6 中删除的 @Depth 注释迁移?

java mysql嵌套搜索实现