为什么private方法加了@Transactional,事务也没有生效?(上)

简介: 为什么private方法加了@Transactional,事务也没有生效?

现在产品期望用户创建和保存逻辑分离:把User实例的创建和保存逻辑拆到两个方法分别进行。

然后,把事务的注解 @Transactional 加在保存数据库的方法上。

1.png

执行程序,异常正常抛出
image.png

事务未回滚

源码解析

debug:

image.png

前一段是 Spring 创建 Bean 的过程。当 Bean 初始化之后,开始尝试代理操作,这是从如下方法开始处理的:

AbstractAutoProxyCreator#postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

继续 debug,直到

AopUtils#canApply

针对切面定义里的条件,确定这个方法是否可被应用创建成代理。

有段 methodMatcher.matches(method, targetClass) 判断这个方法是否符合这样的条件:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   // ...
   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAlllaredMethods(clazz);
      for (Method method : methods) {
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }
   return false;
}

image.png

从 matches() 调用到

AbstractFallbackTransactionAttributeSource#getTransactionAttribute

获取注解中的事务属性,根据属性确定事务的策略。

image.png

接着调用到

computeTransactionAttribute

根据方法和类的类型确定是否返回事务属性:

image.png

当上图中条件判断结果为 true,则返回 null,表明该方法不会被代理,从而导致事务注解不会生效。

那到底是不是 true 呢?

条件1:allowPublicMethodsOnly()

AnnotationTransactionAttributeSource#publicMethodsOnly属性值

image.png

publicMethodsOnly 是通过 AnnotationTransactionAttributeSource 的构造方法初始化的,默认为 true。

image.png

目录
相关文章
|
Java Spring
为什么private方法加了@Transactional,事务也没有生效?(下)
为什么private方法加了@Transactional,事务也没有生效?
647 0
为什么private方法加了@Transactional,事务也没有生效?(下)
需要在Transactional注解指定rollbackFor或者在方法中显示的rollback
由Java阿里巴巴规范提示得,今日探究其原因 1. 先看异常的分类 error是一定会回滚的 这里Exception是异常,他又分为运行时异常RuntimeException和非运行时异常 可查的异常(checked exceptions):Exception下除了RuntimeException外的异常 不可查的异常(unchecked exceptions):RuntimeException及其子类和错误(Error) 如果不对运行时异常进行处理,那么出现运行时异常之后,要么是线程中止,要么是主程序终止。
3641 0
|
10月前
|
Java 编译器 数据库
在事务注解@Transactional中指定rollbackFor
在事务注解@Transactional中指定rollbackFor
81 0
|
Java 编译器 数据库
为什么阿里规定需要在事务注解@Transactional中指定rollbackFor?
为什么阿里规定需要在事务注解@Transactional中指定rollbackFor?
292 0
为什么阿里规定需要在事务注解@Transactional中指定rollbackFor?
|
2月前
|
IDE Java 开发工具
@Transactional 你真的用对了吗?
在日常开发中,`@Transactional`注解常用于声明式事务管理,但其原理和使用不当可能引发问题。本文通过一个实际场景探讨了自调用方法时事务不生效的问题,并分析了潜在风险:数据不一致。为解决此问题,提供了三种方案:1) 将方法移动到其他服务类;2) 使用`AopContext.currentProxy()`获取代理对象;3) 通过`ApplicationContext`获取Bean。最终建议尽量避免自调用事务操作,确保数据一致性。
142 6
|
SQL Java 数据库连接
@Transactional
@Transactional
126 0
|
10月前
|
关系型数据库 Java MySQL
一篇文章学会使用@Transactional
一篇文章学会使用@Transactional
107 0
|
10月前
|
Java 编译器 数据库
@Transactional中指定rollbackFor,弊端以及不能回滚的时候
@Transactional中指定rollbackFor,弊端以及不能回滚的时候
389 3

热门文章

最新文章