- 抛出检查异常导致事务不能正常回滚
- 原因:Spring默认只会回滚非检查异常
RuntimeException和Error
- 解法:配置rollbackFor属性
- 原因:Spring默认只会回滚非检查异常
- 业务方法内自己try-catch异常导致事务不能正确回滚
原因:事务通知只有捉到了目标抛出的异常,才能进行后续的回滚处理,如果目标自己处理掉异常,事务通知无法知悉- 解法1:异常原样抛出
- 解法2:手动设置TransactionStatus.setRollbackOnly()
- AOP 切面顺序导致导致事务不能正确回滚
- 原因:事务切面优先级最低,但如果自定义的切面优先级和他一样,则还是自定义切面在内层,这时若自定义切面没有正确抛
出异常,这时就会导致事务失效 - 解法:同情况2
- 原因:事务切面优先级最低,但如果自定义的切面优先级和他一样,则还是自定义切面在内层,这时若自定义切面没有正确抛
- 非public方法导致的事务失效
- 原因:Spring为方法创建代理、添加事务通知、前提条件都是该方法是public的
- 解法:改为public方法
- 调用本类方法导致传播行为失效
- 原因:本类方法调用不经过代理,因此无法增强,如果同一个类中的两个方法分别为A和B,方法A上没有添加事务注解,方法B上添加了 @Transactional事务注解,方法A调用方法B,则方法B的事务会失效。
- 解法1:依赖注入自己(代理)来调用
- 解法2:通过AopContext拿到代理对象,来调用
- @Transactional方法导致的synchronized 失效
- 原因:synchronized保证的仅是目标方法的原子性,环绕目标方法的还有 commit 等操作,它们并未处于sync块内,所以并不会等待commit完成后在走出sync块,很可能还没commit时已经释放了锁
- 解法:使用 select … for update 替换 select
- final修饰方法导致事务失效
- 原因:spring事务底层使用了aop,也就是通过jdk动态代理或者cglib,帮我们生成了代理类,在代理类中实现的事务功能。但如果某个方法用final修饰了,那么在它的代理类中,就无法重写该方法,而添加事务功能。
Spring事务失效场景详解
猜你喜欢
转载自blog.csdn.net/TangBoBoa/article/details/130412305
今日推荐
周排行