Spring事务原理源码级解析

一、开启事务

1.@EnableTransactionManagement

通过@EnableTransactionManagement注解开启事务,@Import注解可以为容器中导入组件TransactionManagementConfigurationSelector

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement { }

2.TransactionManagementConfigurationSelector

在IOC容器中加载bean定义的时候会回调selectImports方法,返回值是需要导入类的全类名路径数组,然后这个类就会被加载到容器中,其中PROXY分支(默认)会导入AutoProxyRegistrar、ProxyTransactionManagementConfiguration两个类。

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

   @Override
   protected String[] selectImports(AdviceMode adviceMode) {
      switch (adviceMode) {
         //AdviceMode mode() default AdviceMode.PROXY;默认是PROXY
         case PROXY:
            return new String[] {AutoProxyRegistrar.class.getName(),
                  ProxyTransactionManagementConfiguration.class.getName()};
       	...
}

2.1AutoProxyRegistrar

@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
   ...
              if (mode == AdviceMode.PROXY) {
            AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
            ...
*2.1.1InfrastructureAdvisorAutoProxyCreator

AopConfigUtils,最终注册InfrastructureAdvisorAutoProxyCreator到容器中

  @Nullable
  public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
     return registerAutoProxyCreatorIfNecessary(registry, null);
  }

	@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}

InfrastructureAdvisorAutoProxyCreator继承关系,实现了BeanPostProcessor后置处理器,用于处理事务。

image-20211116162349506

注:如果同时启用AOP和事务,那么AOP的后置处理器AnnotationAwareAspectJAutoProxyCreator会覆盖事务的后置处理器InfrastructureAdvisorAutoProxyCreator,因为两者的BeanDefinition是同样的名字AUTO_PROXY_CREATOR_BEAN_NAME,根据内部维护的优先级,AnnotationAwareAspectJAutoProxyCreator优先级大于InfrastructureAdvisorAutoProxyCreator(2>0),这样就会由AnnotationAwareAspectJAutoProxyCreator来处理事务。

//AopConfigUtils内部维护优先级
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);

static {
   // Set up the escalation list...
   APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
   APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
   APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}

*2.2ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration事务相关配置类,其中配置两个Bean:TransactionAttributeSource、TransactionInterceptor。

与AOP不同:AOP是根据@Before、@After等Advise解析成Advisor;事务通过ProxyTransactionManagementConfiguration配置类直接注册一个内置的BeanFactoryTransactionAttributeSourceAdvisor。因为AOP的增强代码是由我们自己编写配置的,而事务的增强代码是由Spring内置实现的。

Advisor包含Advise和Pointcut:其中Advise就是TransactionInterceptor,增强代码用于处理事务;Pointcut切点是TransactionAttributeSourcePointcut,用于匹配Bean是否符合创建动态代理条件(Bean或者Bean方法有@transactional注解),通过AnnotationTransactionAttributeSource对象解析@Transactional注解,一旦解析到就说明有资格创建动态代理。

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {


   //导入internalTransactionAdvisor,包含pointcut和advise
   @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
      BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
      advisor.setTransactionAttributeSource(transactionAttributeSource());//用于解析注解@Transactional
      advisor.setAdvice(transactionInterceptor());//内置Advice
      if (this.enableTx != null) {
        advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
      }
      return advisor;
   }

   /**
    * 事务属性源对象:用于获取事务属性对象
    * @return
    */
   @Bean
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public TransactionAttributeSource transactionAttributeSource() {return new AnnotationTransactionAttributeSource();}

   /**
    * 用户拦截事务方法执行的
    * @return
    */
   @Bean
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public TransactionInterceptor transactionInterceptor() {...}

}

二、解析advisor

与AOP处理流程类似,拿到BeanFactoryTransactionAttributeSourceAdvisor放入到缓存中。

BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans

public List<Advisor> findAdvisorBeans() {

   ...
      advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
      this.cachedAdvisorBeanNames = advisorNames;
   }
   ...
   //ioc容器中找到了我们配置的BeanFactoryTransactionAttributeSourceAdvisor
   for (String name : advisorNames) {
      //判断是不是一个合适的bean
      if (isEligibleBean(name)) {
         ...
         else {
            try {
               //显示的调用getBean方法方法创建我们的BeanFactoryTransactionAttributeSourceAdvisor返回
               advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
            ...

三、创建动态代理

与AOP处理流程类似,拿到缓存中的BeanFactoryTransactionAttributeSourceAdvisor;匹配Pointcut时类级别的筛选会永远返回True,方法级别的筛选:本方法是否有@Transactional—>接口方法是否有@Transactional—>父类方法是否有@Transactional—>本类是否有@Transactional—>接口是否有@Transactional—>父类是否有@Transactional。

1.matches

TransactionAttributeSourcePointcut#matches

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

   @Override
   public boolean matches(Method method, @Nullable Class<?> targetClass) {
      if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
         return false;
      }
      /**
       * 获取TransactionAttributeSource对象
       */
      TransactionAttributeSource tas = getTransactionAttributeSource();
      // 通过getTransactionAttribute看是否有@Transactional注解
      return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
   }
  ...

2.getTransactionAttribute

AbstractFallbackTransactionAttributeSource#getTransactionAttribute

@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   ...
      
      TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
     ...
}

3.computeTransactionAttribute

AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   //判断我们的事务方法上的修饰符是不是public的
   if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
   }

   // 拿到具体实现方法
   Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

   //第一步,解析具体方法
   TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
   if (txAttr != null) {
      return txAttr;
   }

   //第二步:解析方法所在实现类
   txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
   if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
      return txAttr;
   }
   。。。
     
	@Nullable
	protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);     

4.findTransactionAttribute

AnnotationTransactionAttributeSource#findTransactionAttribute实现

  @Override
  @Nullable
  protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
     return determineTransactionAttribute(clazz);
  }

	@Nullable
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		//获取注解解析器,3种,一般使用Spring的
		for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
			//通过注解解析器去解析方法上的注解
			TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}
image-20211117135504477

5.parseTransactionAnnotation

SpringTransactionAnnotationParser#parseTransactionAnnotation

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

   @Override
   @Nullable
   public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
      //从element对象中获取@Transactional注解 然后把注解属性封装到了AnnotationAttributes
      AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
            element, Transactional.class, false, false);
      if (attributes != null) {
         //解析出真正的事务属性对象
         return parseTransactionAnnotation(attributes);
      }
      else {
         return null;
      }
   }

6.createProxy

匹配成功之后就会创建动态代理,流程与AOP类似。

四、调用方法

1.invoke

责任链调用方式与AOP类似,最终会调用到TransactionInterceptor#invoke方法

  @Override
  @Nullable
  public Object invoke(MethodInvocation invocation) throws Throwable {
     ...
     return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
  }

*2.invokeWithinTransaction

TransactionAspectSupport#invokeWithinTransaction,处理事务相关逻辑,包括开启、回滚、提交等。

@Nullable
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
      final InvocationCallback invocation) throws Throwable {
		...
   //处理声明式事务
   if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      //开启事务
      //根据事务传播行为,判断是否有必要
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

      Object retVal;
      try {
         //调用钩子函数回调目标方法
         retVal = invocation.proceedWithInvocation();
      }
      catch (Throwable ex) {
         //回滚事务
         //抛出异常时调用
         completeTransactionAfterThrowing(txInfo, ex);
         throw ex;
      }
      finally {
         //清空线程变量中transactionInfo的值
         cleanupTransactionInfo(txInfo);
      }
      //提交事务
      commitTransactionAfterReturning(txInfo);
      return retVal;
   }
   // 编程式事务
      ...
}

*3.createTransactionIfNecessary

TransactionAspectSupport#createTransactionIfNecessary,根据事务传播行为判断是否开启事务,以及处理嵌套事务等逻辑。

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
      @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
  	...
         //获取一个事务状态
         status = tm.getTransaction(txAttr);
   	...
   //把事物状态和事物属性等信息封装成一个TransactionInfo对象
   return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

4.getTransaction

AbstractPlatformTransactionManager#getTransaction

@Override
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
		//获取事务对象
		Object transaction = doGetTransaction();  
   ...
     
		//判断是不是已经存在了事务(嵌套事务)
		//通过ConnectionHolder判断,如果为null,说明是外层事务;如果不为null,说明已经开启了事务。
		if (isExistingTransaction(transaction)) {
			//处理存在的事务
      //嵌套事务就不会走下面逻辑
			return handleExistingTransaction(definition, transaction, debugEnabled);
		}
  
  	...
   //判断事务传播行为,默认PROPAGATION_REQUIRED   
   //PROPAGATION_MANDATORY:表示必须运行在事务中,若当前没有事务就抛出异常
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
      ...
   }
   //以下三个都会开启一个事务
   //PROPAGATION_REQUIRED:当前存在事务就加入到当前的事务,没有就新开一个
   //PROPAGATION_REQUIRES_NEW:新开一个事务,若当前存在事务就挂起当前事务
   //PROPAGATION_NESTED:表示如果当前正有一个事务在运行中,则该方法应该运行在一个嵌套的事务中,被嵌套的事务可以独立于封装事务进行提交或者回滚(保存点),如果封装事务不存在,行为就像PROPAGATION_REQUIRES_NEW
   else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
         definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
         definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
       //挂起当前事务
       //因为经过了isExistingTransaction(transaction)判断当前是不存在事务的,所以传递null表示不挂起事务
      SuspendedResourcesHolder suspendedResources = suspend(null);
      ...
      try {
         ...
         //开启一个新的事务
         doBegin(transaction, definition);
         //把当前的事务属性绑定到线程变量去(事务隔离级别、事务激活、是否只读、事务名称)
         prepareSynchronization(status, definition);
         return status;
      ...

doGetTransaction,获取事务对象

@Override
protected Object doGetTransaction() {
   ...
   //TransactionSynchronizationManager事务同步管理器对象,该类中都是局部线程变量,用来保存当前事务的信息。
   //第一次从这里去线程变量中获取ConnectionHolder(数据库连接持有者),以数据源obtainDataSource为key,会返回null,因为还没有存放。
   //ConnectionHolder为null,说明是外层事务;如果不为null,说明已经开启了事务。
   //第二次进来(嵌套事务)会获取到ConnectionHolder 
   ConnectionHolder conHolder =
         (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
   txObject.setConnectionHolder(conHolder, false);
   //返回事务对象
   return txObject;
}

doBegin,开启事务

@Override
protected void doBegin(Object transaction, TransactionDefinition definition) {
   ...
         //获取配置的数据源的连接 
         Connection newCon = obtainDataSource().getConnection();
         ...
         //把数据库连接包装成一个ConnectionHolder对象,然后设置到txObject对象中
         txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
      }
      ...
         //开启事务
         con.setAutoCommit(false);
      ...
}

handleExistingTransaction,处理嵌套事务

private TransactionStatus handleExistingTransaction(
      TransactionDefinition definition, Object transaction, boolean debugEnabled) throws TransactionException {

   //NEVER 存在外部事务:抛出异常
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {...}

   //NOT_SUPPORTED 存在外部事务:挂起外部事务,不创建新事务
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {...}

   //REQUIRES_NEW 存在外部事务:挂起外部事务,创建新事务
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {...}

   //NESTED 存在外部事务:融合到外部事务中
   if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {...}

   ...
}

suspend,挂起事务

@Nullable
protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
   ...
         if (transaction != null) {
         	//挂起事务,移除ConnectionHolder,设置为null
         	//移除后其他线程就无法获取外层事务,实现挂起
            suspendedResources = doSuspend(transaction);
         }
         //获取外层事务(已存在事务)名称并清空线程变量
         ...
         //获取外层事务(已存在事务)是否是只读事务并清空线程变量
         ...
         //获取外层事务(已存在事务)的隔离级别并清空线程变量
         ...
         //获取外层事务(已存在事务)是否激活并清空线程变量
         ...
         //把从线程变量中获取出来的外层事务(已存在事务)属性封装为SuspendedResourcesHolder返回
         //TransactionSynchronizationManager-->SuspendedResourcesHolder
         return new SuspendedResourcesHolder(
               suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
      ...
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值