spring事务常见问题、异常分析和解决方法
最后更新于:2022-04-01 15:55:44
1.spring事务超时transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException;
可能原因1:spring事务设置的时间比较短。
解决方法:把spring事务设置长一点,如果事务中有很多复杂的查询及更新操作,取消方法上的事务注解,然后把查询操作整理后放在方法最前面,把更新操作放在一块,用自定义事务把更新操作放进去。
可能原因2:可能是mysql数据库InnoDB使用缓冲池设置小了,事务隔离级别不对。
解决方法:把缓存mysql数据库InnoDB使用缓冲池设置大些,同时把事务隔离级别由默认的REPEATABLE_READ级别改为READ_COMMITTED(关于事务级别在这里不再描述);
可能原因3:查询、更新sql效率不高;
解决方法:加索引,注意根据不同的数据库编写不同的表及where条件顺序。
2.spring事务(Transaction )报 marked as rollback-only异常的原因及解决方法
在spring中,在事务方法中调用多个事务方法时,spring将会把这些事务合二为一。
当整个方法中每个子方法没报错时,整个方法执行完才提交事务(大家可以使用debug测试),
如果某个子方法有异常,spring将该事务标志为rollback only。如果这个子方法没有将异常往上整个方法抛出或整个方法未往上抛出,
那么改异常就不会触发事务进行回滚,事务就会在整个方法执行完后就会提交,
这时就会造成Transaction rolled back because it has been marked as rollback-only的异常;
如果没看懂可以看[《 spring事务(Transaction )报 marked as rollback-only异常的原因及解决方法》](http://blog.csdn.net/mr_smile2014/article/details/49455483)这篇文章
3.已经定义事务了,为什么事务不回滚。
检查自己的代码中是不是用try...catch把异常获取了,而没有往上抛。如果没有往上抛,事务就会以为一切都很顺利没有出错,最后就会提交事务。如下面的代码,出现异常就不会回滚:
~~~
@Transactional(rollbackFor = { Exception.class })
public void test() {
try {
doDbStuff1();
doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。
} catch (Exception e) {
e.printStackTrace();
}
}
~~~
我们把上面的代码改成下面的代码,出现异常就会回滚:
~~~
@Transactional(rollbackFor = { Exception.class })
public void test() {
try {
doDbStuff1();
doDbStuff2();//假如这个操作数据库的方法会抛出异常,现在方法doDbStuff1()对数据库的操作 不会回滚。
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
~~~
4.Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [org.springframework.transaction.PlatformTransactionManager] is defined;
原因是没有找到对应的bean,检查spring的版本是否正确;