@Transactional失效的3种场景及解决办法

本文探讨了@Transactional注解在Java Spring环境中可能出现的三种失效场景:1) 非public方法上的注解无效;2) 类内部直接调用带注解的方法;3) 方法捕获异常未重新抛出导致事务无法回滚。分析了这些场景的原因,并提供了相应的解决办法。
摘要由CSDN通过智能技术生成

第一种 Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用。

第二种 在类内部调用,调用类内部@Transactional标注的方法,这种情况下也会导致事务不开启。

第三种 事务方法内部捕捉了异常,没有抛出新的异常,导致事务操作不会进行回滚。

@Transactional注解不起作用原理分析
第一种场景分析:
@Transactional注解标注方法修饰符为非public时,@Transactional注解将会不起作用。这里分析 的原因是,@Transactional是基于动态代理实现的,@Transactional注解实现原理中分析了实现方法,在bean初始化过程中,对含有@Transactional标注的bean实例创建代理对象,这里就存在一个spring扫描@Transactional注解信息的过程,不幸的是源码中体现,标注@Transactional的方法如果修饰符不是public,那么就默认方法的@Transactional信息为空,那么将不会对bean进行代理对象创建或者不会对方法进行代理调用@Transactional注解实现原理中,介绍了如何判定一个bean是否创建代理对象,大概逻辑是。根据spring创建好一个aop切点BeanFactoryTransactionAttributeSourceAdvisor实例,遍历当前bean的class的方法对象,判断方法上面的注解信息是否包含@Transactional,如果bean任何一个方法包含@Transactional注解信息,那么就是适配这个BeanFactoryTransactionAttributeSourceAdvisor切点。则需要创建代理对象,然后代理逻辑为我们管理事务开闭逻辑。
spring源码中,在拦截bean的创建过程,寻找bean适配的切点时,运用到下面的方法,目的就是寻找方法上面的@Transactional信息,如果有,就表示切点BeanFactoryTransactionAttributeSourceAdvisor能够应用(canApply)到bean中,
AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   
   Assert.notNull(pc, "Pointcut must not be null");
   if (!pc.getClassFilter().matches(targetClass)) {
   
      return false;
   }

   MethodMatcher methodMatcher = pc.getMethodMatcher();
   if (methodMatcher == MethodMatcher.TRUE) {
   
      // No need to iterate the methods if we're matching any method anyway...
      return true;
   }

   IntroductionAwareMethodMatcher introductionAwareMethodMatcher 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值