springboot 事务嵌套问题_精准且详细的讲解一下:深入“Springboot”源码分析的事务问题...

502ecd8c1bab64faaeaab858b295a29e.png

摘要

事务在后端开发中无处不在,是数据一致性的最基本保证。要明白进事务的本质就是进到事务切面的代理方法中,最常见的是同一个类的非事务方法调用一个加了事务注解的方法没进入事务。我们以 cglib 代理为例,由于 Spring 的对于 cglib AOP 代理的实现,进入被代理方法的时候实际上已经离开了“代理这一层壳子”,可以认为代码走到的是一个朴素的 bean,调用同一个 bean 中方法自然与代理没有半毛钱关系了。 一般对于声明式事务都是以调用另一个类的加了 @Transactional 注解的 public 方法作为入口的。

spring事务关键处理流程

  • EnableTransactionManagement注解导入TransactionManagementConfigurationSelector
  • TransactionManagementConfigurationSelector加载InfrastructureAdvisorAutoProxyCreator(但不一定是它,一般都是AnnotationAwareAspectJAutoProxyCreator),BeanFactoryTransactionAttributeSourceAdvisor,TransactionInterceptor
    AnnotationAwareAspectJAutoProxyCreator在ioc流程一个关键步骤是查找Advisor,有两个方面,第一是实现了Advisor接口的类,第二是基于注解Aspectj。关键是BeanFactoryTransactionAttributeSourceAdvisor被加载进了代理缓存
  • 代理调用方法的时候会执行DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice,这个时候就会将我们的
    “BeanFactoryTransactionAttributeSourceAdvisor” 派上用处,最主要的还是它里面的TransactionAttributeSourcePointcut进行匹配,执行TransactionInterceptor的方法

TransactionInterceptor

 @Override
 @Nullable
 public Object invoke(MethodInvocation invocation) throws Throwable {
    
 // Work out the target class: may be {@code null}.
 // The TransactionAttributeSource should be passed the target class
 // as well as the method, which may be from an interface.
 Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
 
 // Adapt to TransactionAspectSupport's invokeWithinTransaction...
 return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
 }

TransactionAspectSupport

@Nullable
 protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
 final InvocationCallback invocation) throws Throwable {
    
 
 // If the transaction attribute is null, the method is non-transactional.
 TransactionAttributeSource tas = getTransactionAttributeSource();
 final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
 final PlatformTransactionManager tm = determineTransactionManager(txAttr);
 final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
 
 if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
    
 // Standard transaction demarcation with getTransaction and commit/rollback calls.
 TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
 
 Object retVal;
 try {
    
 // This is an around advice: Invoke the next interceptor in the chain.
 // This will normally result in a target object being invoked.
 retVal = invocation.proceedWithInvocation();
 }
 catch (Throwable ex) {
    
 // target inv
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值