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修饰了,那么在它的代理类中,就无法重写该方法,而添加事务功能。

猜你喜欢

转载自blog.csdn.net/TangBoBoa/article/details/130412305