侧边栏壁纸
博主头像
landery博主等级

行李箱里装不下我想去的远方

  • 累计撰写 45 篇文章
  • 累计创建 26 个标签
  • 累计收到 6 条评论

目 录CONTENT

文章目录

Spring @Transactional 注解自调用问题记录

landery
2022-06-10 / 0 评论 / 0 点赞 / 216 阅读 / 730 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-06-10,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

在一个Spring boot项目中,我利用@Transactional 注解进行事务管理,不许需要手动写事务操作,发生了Spring AOP的自调用问题,事务失效,记录一下。原因是我在同一个类中调用了使用@Transactional注解的方法,使得该注解失效。

以下文章内容出处:https://blog.csdn.net/weixin_46204056/article/details/124293908

@Transactional 的作用范围

  • 方法 :推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到 public 方法上,否则不生效。
  • :如果这个注解使用在类上的话,表明该注解对该类中所有的 public 方法都生效。
  • 接口:不推荐在接口上使用。因为这只有在使用基于接口的代理时它才会生效。

@Transactional 事务注解原理

@Transactional 的工作机制是基于 AOP 实现的,AOP 又是使用动态代理实现的。如果目标对象实现了接口,默认情况下会采用 JDK 的动态代理,如果目标对象没有实现了接口,会使用 CGLIB 动态代理。

如果一个类或者一个类中的 public 方法上被标注@Transactional 注解的话,Spring 容器就会在启动的时候为其创建一个代理类,在调用被@Transactional 注解的 public 方法的时候,实际调用的是,TransactionInterceptor 类中的 invoke()方法。这个方法的作用就是在目标方法之前开启事务,方法执行过程中如果遇到异常的时候回滚事务,方法调用完成之后提交事务。

Spring AOP 自调用问题

若同一类中的其他没有 @Transactional 注解的方法内部调用有 @Transactional 注解的方法,有@Transactional 注解的方法的事务会失效。

这是由于Spring AOP代理的原因造成的,因为只有当 @Transactional 注解的方法在类以外被调用的时候,Spring 事务管理才生效。

MyService 类中的method1()调用method2()就会导致method2()的事务失效

@Service
public class MyService {

private void method1() {
     method2();
     //......
}
@Transactional
 public void method2() {
     //数据库操作
  }
}

解决办法就是避免同一类中自调用或者使用 AspectJ 取代 Spring AOP 代理。

@Transactional 的使用注意事项总结

  • @Transactional 注解只有作用到 public 方法上事务才生效,不推荐在接口上使用;
  • 避免同一个类中调用 @Transactional 注解的方法,这样会导致事务失效;
  • 正确的设置 @Transactional 的 rollbackFor 和 propagation 属性,否则事务可能会回滚失败;
  • 被 @Transactional 注解的方法所在的类必须被 Spring 管理,否则不生效;
    底层使用的数据库必须支持事务机制,否则不生效;
0

评论区