Spring事务失效场景详解

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值