java.sql.SQLException: Can''t call commit when autocommit=true

极客星河引
• 阅读 2996

在使用java操作数据库,创建数据库连接对象,创建事务管理器(开启事务,提交事务,回滚事务),运行代码后,报错如下

java.sql.SQLException: Can't call commit when autocommit=true
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:65)
at com.mysql.cj.jdbc.ConnectionImpl.commit(ConnectionImpl.java:814)
at com.alibaba.druid.pool.DruidPooledConnection.commit(DruidPooledConnection.java:749)
at com.bigdata.utils.TransactionManager.commit(TransactionManager.java:29)
at com.bigdata.service.impl.AccountServiceImpl.transfer(AccountServiceImpl.java:29)
at com.bigdata.test.SpringTansferTest.test(SpringTansferTest.java:21)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

相关代码如下
java.sql.SQLException: Can''t call commit when autocommit=true
java.sql.SQLException: Can''t call commit when autocommit=true

错误提示重点在于第一句,意思是如果当前自动提交事务的功能是开启的,就不能调用commit方法.

但是就像我上面的代码,实际上在begin()方法中已经将自动提交事务的功能关闭了(setAutoCommit(false)),而在另外的代码中也可以保证在提交事务的方法commit()执行之前, 先执行begin()方法

最后发现原因是创建数据库连接对象那里,从连接池获取数据库连接对象是在成员方法getConnection()中实现的. 那么每次调用这个方法时, 不能保证两次获取的是同一连接. 所以在当前连接关闭了自动提交事务, 但是下一个连接不一定是这种情况.

所以处理方式就是将从连接池获取连接的操作移到成员方法外,确保使用的是同一连接
java.sql.SQLException: Can''t call commit when autocommit=true

点赞
收藏
评论区
推荐文章
梦
5年前
手动开启事务回滚
有些时候进行一些判断后,根据当前状态需要进行事务回滚,用以下代码实现//手动开启事务回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
Stella981 Stella981
4年前
Redis事务,持久化,哨兵机制
1Redis事务基本事务指令Redis提供了一定的事务支持,可以保证一组操作原子执行不被打断,但是如果执行中出现错误,事务不能回滚,Redis未提供回滚支持。multi 开启事务exec 执行事务127.0.0.1:6379multiOK127.0.0.
Stella981 Stella981
4年前
PHP 对 mysql 的事务处理
mysqlmysql事务处理php代码实现事务的处理可以通过PHP预定义类mysqli的以下方法实现。autocommit(boolean):该方法用于限定查询结果是否自动提交,如果该方法的参数为true则自动提交,如果参数为false则关闭自动提交。MySQL数据库默认为自动提交。rollback():利用mysqli类中的该
Easter79 Easter79
4年前
Spring事务回滚情况
spring默认非嵌套调用的情况Spring框架的事务基础架构代码将默认地只在抛出运行时和uncheckedexceptions时才标识事务回滚。也就是说,当抛出一个RuntimeException或其子类例的实例时。(Errors也一样默认地标识事务回滚。)从事务方法中抛出的Checkedexceptions将不
Wesley13 Wesley13
4年前
MySql学习17
一.数据库事务的四大特性(ACID)如果一个数据库声称支持事务的操作,那么该数据库必须要具备以下四个特性:原子性(Atomicity):原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚,这和前面两篇博客介绍事务的功能是一样的概念,因此事务的操作如果成功就必须要完全应用到数据库,如果操
Wesley13 Wesley13
4年前
MySQL transaction
MySQLtransaction(数据库的事务)数据库事务(DatabaseTransaction),是指作为单个逻辑工作单元执行的一系列操作。要么完全执行,要么完全地不执行。ACID事务必须具备ACID四个特性原子性(Atomicity)原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚。一致性(Consistency)
Stella981 Stella981
4年前
SQL如何使用快照恢复之前的数据
什么是快照数据库快照是SQLserver2005的一个新功能。给出的定义如下数据库快照是数据库的只读静态视图。在创建时每个数据库快照在事务上都与源数据库一致。在创建数据库快照时,源数据库通常会有打开的事务。在快照可以使用之前,打开的事务会回滚以使数据库快照在事务上取得一致。reg:!(https://oscimg.oschina.ne
Easter79 Easter79
4年前
SQL如何使用快照恢复之前的数据
什么是快照数据库快照是SQLserver2005的一个新功能。给出的定义如下数据库快照是数据库的只读静态视图。在创建时每个数据库快照在事务上都与源数据库一致。在创建数据库快照时,源数据库通常会有打开的事务。在快照可以使用之前,打开的事务会回滚以使数据库快照在事务上取得一致。reg:!(https://oscimg.oschina.ne
Stella981 Stella981
4年前
RabbitMQ 如何保证消息的可靠性
一条消费成功被消费经历了生产者MQ消费者,因此在这三个步骤中都有可能造成消息丢失。一消息生产者没有把消息成功发送到MQ1.1事务机制AMQP协议提供了事务机制,在投递消息时开启事务支持,如果消息投递失败,则回滚事务。自定义事务管理器@Configuration
Spring事务实现原理
1、引言spring的springtx模块提供了对事务管理支持,使用spring事务可以让我们从复杂的事务处理中得到解脱,无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。spring事务有编程式事务和声明式事务两种实现方式。编程式事务是通过编写代
Spring事务实现原理
作者:京东零售范锡军1、引言spring的springtx模块提供了对事务管理支持,使用spring事务可以让我们从复杂的事务处理中得到解脱,无需要去处理获得连接、关闭连接、事务提交和回滚等这些操作。spring事务有编程式事务和声明式事务两种实现方式。编