spring事务源码初步分析

首先看看@EnableTransactionManagement注解源码,发现该注解是导入了TransactionManagementConfigurationSelector组件

@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

在看看导入的组件有什么作用

protected String[] selectImports(AdviceMode adviceMode) {
        switch(adviceMode) {
        case PROXY:
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
        case ASPECTJ:
            return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
        default:
            return null;
        }
    }

导入的组件是根据我们的AdviceMode注解设置再一次来导入一些组件,而AdviceModel属性决定我们事务底层使用的是JDK动态代理还是AspectJ,如果是PROXY则导入AutoProxyRegistrar. 和 ProxyTransactionManagementConfiguration这两个组件,默认是使用JDK动态代理,我认为要理解事务的执行流程,就应该搞懂这两个组件做了什么工作

先看AutoProxyRegistrar,可以看到,该组件大概是用来注册一些bean的

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar

在看

if (mode == AdviceMode.PROXY) {
                        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                        if ((Boolean)proxyTargetClass) {
                            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                            return;
                        }
                    }

如果我们在注解中设置了AdviceModel是使用jdk动态代理,就会使用AOP设置工具类的注册一个自动代理创建器

AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);

进入方法内部,实际上就是调用这个方法

registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);

InfrastructureAdvisorAutoProxyCreator有什么作用呢?
就是利用后置处理器机制,在对象创建以后,包装对象,返回一个代理对象(增强器),利用代理对象执行方法利用拦截器链进行调用
bean初始化前

public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        Object cacheKey = this.getCacheKey(beanClass, beanName); //先从缓存(相当于容器吧)中看看有没有这个bean
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }

            if (this.isInfrastructureClass(beanClass) || this.shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        TargetSource targetSource = this.getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }

            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = this.createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        } else {
            return null;
        }
    }

bean初始化后进行包装 —> this.wrapIfNecessary(bean, beanName, cacheKey);

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

        return bean;
    }

现在再来看这个组件ProxyTransactionManagementConfiguration
核心方法

public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(this.transactionAttributeSource()); //设置事务属性
        advisor.setAdvice(this.transactionInterceptor()); //事务拦截器
        if (this.enableTx != null) {
            advisor.setOrder((Integer)this.enableTx.getNumber("order"));
        }

        return advisor;
    }

先看事务属性的设置
实际上就是解析事务注解中的一些配置的属性

public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }

分情况。三种事务注解

 this.annotationParsers.add(new SpringTransactionAnnotationParser());
            if (jta12Present) {
                this.annotationParsers.add(new JtaTransactionAnnotationParser());
            }

            if (ejb3Present) {
                this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
            }

当然我们使用的就是spring的事务注解
点进去看注解解析的方法

protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
        Propagation propagation = (Propagation)attributes.getEnum("propagation");
        rbta.setPropagationBehavior(propagation.value());
        Isolation isolation = (Isolation)attributes.getEnum("isolation");
        rbta.setIsolationLevel(isolation.value());
        rbta.setTimeout(attributes.getNumber("timeout").intValue());
        rbta.setReadOnly(attributes.getBoolean("readOnly"));
        rbta.setQualifier(attributes.getString("value"));
        List<RollbackRuleAttribute> rollbackRules = new ArrayList();
        Class[] var6 = attributes.getClassArray("rollbackFor");
        ....

最后,事务核心就是在于这个事务的拦截器上advisor.setAdvice(this.transactionInterceptor());

public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor(); // 实例化一个事务拦截器
        interceptor.setTransactionAttributeSource(this.transactionAttributeSource()); //设置事务属性
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager); //如果有事务管理器,就加上事务管理器
        }

        return interceptor;
    }

这个事务拦截器实现了方法拦截器的接口

TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable

所以直接看他重写的invoke方法

public Object invoke(MethodInvocation invocation) throws Throwable {
        Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
        Method var10001 = invocation.getMethod();
        invocation.getClass();
        return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed); // 事务处理的核心方法
    }

看看这个方法invokeWithinTransaction

TransactionAttributeSource tas = this.getTransactionAttributeSource();
        TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null; //获取相关事务属性
        PlatformTransactionManager tm = this.determineTransactionManager(txAttr); //设置事务平台管理器
        String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);//获取要执行的事务方法
        Object result; //方法返回值

如何获取平台事务管理器

this.determineQualifiedTransactionManager(this.beanFactory, qualifier);//如果我们在@Transactional中上有配置,就根据名称获取

 defaultTransactionManager = (PlatformTransactionManager)this.beanFactory.getBean(PlatformTransactionManager.class);//否则就从ioc容器中根据类型获取

事务处理核心部分

TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
            result = null;  
//如果是一个事务方法,就在这里开启事务
            try {
                result = invocation.proceedWithInvocation(); //事务方法执行
            } catch (Throwable var17) {
                this.completeTransactionAfterThrowing(txInfo, var17); //如果事务方法出现异常,执行回滚事务
                throw var17;
            } finally {
                this.cleanupTransactionInfo(txInfo);
            }

            this.commitTransactionAfterReturning(txInfo); //最后提交事务
            return result; //方法返回值

事务回滚

try {
                    txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
                } catch (TransactionSystemException var6) {
                    this.logger.error("Application exception overridden by rollback exception", ex);
                    var6.initApplicationException(ex);
                    throw var6;
                } catch (Error | RuntimeException var7) {
                    this.logger.error("Application exception overridden by rollback exception", ex);
                    throw var7;
                }

所以整一个事务方法执行流程大概是这样的
在目标方法执行的时候;

  1. 执行拦截器链;
  2. 事务拦截器:
    1. 先获取事务相关的属性
    2. 再获取PlatformTransactionManager,如果事先没有添加指定任何transactionmanger最终会从容器中按照类型获取一个PlatformTransactionManager;
    3. 执行目标方法
      如果异常,获取到事务管理器,利用事务管理回滚操作;
      如果正常,利用事务管理器,提交事务
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值