Spring5.x Transaction 自定义事务标签

1、自定义事务标签XML配置

<tx: annotation-driven transaction-manager="transactionManager" mode="aspectj "/>

 

2、自定义事务标签命名空间处理器 TxNamespaceHandler


public class TxNamespaceHandler extends NamespaceHandlerSupport {

static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";

 

static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";

 

static String getTransactionManagerName(Element element) {

 return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?

   element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);

}

 

 

@Override

public void init() {

 registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());

 registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());

 registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());

}

}

 

3、自定义事务标签解析器 AnnotationDrivenBeanDefinitionParser

3.1 解析{@code <tx:annotation-driven/>}标签

public BeanDefinition parse(Element element, ParserContext parserContext) {

 // 注册事务事件监听器

 registerTransactionalEventListenerFactory(parserContext);

 String mode = element.getAttribute("mode");

 if ("aspectj".equals(mode)) {

  // mode="aspectj" AspectJ方式进行事物切入

  registerTransactionAspect(element, parserContext);

  if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {

   registerJtaTransactionAspect(element, parserContext);

  }

 }

 else {

  // mode="proxy" Spring Aop方式进行事物切入

  AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);

 }

 return null;

}

 

3.2 AspectJ方式进行事务切入

// 注册类为AnnotationTransactionAspect的BeanDefinition,加载字节码时由AspectJ织入增强

public static final String TRANSACTION_ASPECT_CLASS_NAME =

  "org.springframework.transaction.aspectj.AnnotationTransactionAspect";

private void registerTransactionAspect(Element element, ParserContext parserContext) {

 String txAspectBeanName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME;

 String txAspectClassName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_CLASS_NAME;

 if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) {

  RootBeanDefinition def = new RootBeanDefinition();

  def.setBeanClassName(txAspectClassName);

  def.setFactoryMethodName("aspectOf");

  registerTransactionManager(element, def);

  parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName));

 }

}

 

// 注册类为JtaAnnotationTransactionAspect的BeanDefinition,加载字节码时由AspectJ织入增强

public static final String JTA_TRANSACTION_ASPECT_CLASS_NAME =

  "org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect";

private void registerJtaTransactionAspect(Element element, ParserContext parserContext) {

 String txAspectBeanName = TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_BEAN_NAME;

 String txAspectClassName = TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CLASS_NAME;

 if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) {

  RootBeanDefinition def = new RootBeanDefinition();

  def.setBeanClassName(txAspectClassName);

  def.setFactoryMethodName("aspectOf");

  registerTransactionManager(element, def);

  parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName));

 }

}

 

private static void registerTransactionManager(Element element, BeanDefinition def) {

 def.getPropertyValues().add("transactionManagerBeanName",

   TxNamespaceHandler.getTransactionManagerName(element));

}


3.3 Spring Aop方式进行事务切入 AopAutoProxyConfigurer

private static class AopAutoProxyConfigurer {

 public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {

  AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

 

  String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;

  if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {

   Object eleSource = parserContext.extractSource(element);

 

   // Create the TransactionAttributeSource definition.

   RootBeanDefinition sourceDef = new RootBeanDefinition(

     "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");

   sourceDef.setSource(eleSource);

   sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

   String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

 

   // Create the TransactionInterceptor definition.

   RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);

   interceptorDef.setSource(eleSource);

   interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

   registerTransactionManager(element, interceptorDef);

   interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));

   String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

 

   // Create the TransactionAttributeSourceAdvisor definition.

   RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);

   advisorDef.setSource(eleSource);

   advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

   advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));

   advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);

   if (element.hasAttribute("order")) {

    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));

   }

   parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

 

   CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);

   compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));

   compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));

   compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));

   parserContext.registerComponent(compositeDef);

  }

 }

}

 

3.3.1 注册事务代理自动创建器 InfrastructureAdvisorAutoProxyCreator

3.3.1.1 AopNamespaceUtils.registerAutoProxyCreatorIfNecessary

public static void registerAutoProxyCreatorIfNecessary(

  ParserContext parserContext, Element sourceElement) {

 

 BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(

   parserContext.getRegistry(), parserContext.extractSource(sourceElement));

 // 是否基于类创建代理、是否暴露代理对象

 useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);

 registerComponentIfNecessary(beanDefinition, parserContext);

}

 

3.3.1.2 AopConfigUtils.registerAutoProxyCreatorIfNecessary

public static BeanDefinition registerAutoProxyCreatorIfNecessary(

  BeanDefinitionRegistry registry, @Nullable Object source) {

 

 // 注册代理自动创建器 InfrastructureAdvisorAutoProxyCreator

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

}

 

3.3.1.3 代理自动创建器 InfrastructureAdvisorAutoProxyCreator

仅考虑 infrastructure Advisor Bean 的自动代理创建者,忽略任何应用程序定义的Advisors。

 

Spring5.x Transaction 自定义事务标签

 

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

@Nullable

private ConfigurableListableBeanFactory beanFactory;

 

// 保存beanFactory

@Override

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {

 super.initBeanFactory(beanFactory);

 this.beanFactory = beanFactory;

}

 

// 查找Advisor时判断是否是适用的:只有是系统定义的角色为ROLE_INFRASTRUCTURE才是适用的,用户自定义的等Advisor将被忽略

@Override

protected boolean isEligibleAdvisorBean(String beanName) {

 return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&

   this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);

}

}

 

3.3.1.4 查找匹配Bean的Advisor(系统定义的角色为ROLE_INFRASTRUCTURE的Advisor)

动态AOP-Spring AOP 基于@AspectJ》一文中已经分析过,代理自动创建者。在其父类AbstractAdvisorAutoProxyCreator方法getAdvicesAndAdvisorsForBean获取匹配当前Bean的AdvicesAndAdvisors时,会判断哪些Advice或Advisor是候选者。

 

// 查找匹配Bean的AdvicesAndAdvisor

protected Object[] getAdvicesAndAdvisorsForBean(

  Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

 

 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);

 if (advisors.isEmpty()) {

  return DO_NOT_PROXY;

 }

 return advisors.toArray();

}

 

// 查找匹配指定Bean的AdvicesAndAdvisor

 

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {

 List<Advisor> candidateAdvisors = findCandidateAdvisors();

// 匹配指定Bean的Advisor,传送门3.3.2.5

 List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);

 extendAdvisors(eligibleAdvisors);

 if (!eligibleAdvisors.isEmpty()) {

  eligibleAdvisors = sortAdvisors(eligibleAdvisors);

 }

 return eligibleAdvisors;

}

 

// 查找所有的Advisor

protected List<Advisor> findCandidateAdvisors() {

 Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");

// 调用的是BeanFactoryAdvisorRetrievalHelperAdapter

 return this.advisorRetrievalHelper.findAdvisorBeans();

}

 

// Advisor查找辅助类

private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

 public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {

  super(beanFactory);

 }

 

 @Override

 protected boolean isEligibleBean(String beanName) {

  // 调用了InfrastructureAdvisorAutoProxyCreator.isEligibleAdvisorBean

  return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);

 }

}

 

3.3.1.5 过滤匹配Bean的Advisor

protected List<Advisor> findAdvisorsThatCanApply(

  List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

 

 ProxyCreationContext.setCurrentProxiedBeanName(beanName);

 try {

  return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);

 }

 finally {

  ProxyCreationContext.setCurrentProxiedBeanName(null);

 }

}

 

AopUtils.findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {

 if (candidateAdvisors.isEmpty()) {

  return candidateAdvisors;

 }

 List<Advisor> eligibleAdvisors = new ArrayList<>();

 for (Advisor candidate : candidateAdvisors) {

  if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {

   eligibleAdvisors.add(candidate);

  }

 }

 boolean hasIntroductions = !eligibleAdvisors.isEmpty();

 // 包含解析自定义事物标签时注入的BeanFactoryTransactionAttributeSourceAdvisor

 for (Advisor candidate : candidateAdvisors) {

  if (candidate instanceof IntroductionAdvisor) {

   // already processed

   continue;

  }

  if (canApply(candidate, clazz, hasIntroductions)) {

   eligibleAdvisors.add(candidate);

  }

 }

 return eligibleAdvisors;

}

 

AopUtils.canApply

public static boolean canApply(Advisor advisor, Class<?> targetClass) {

 return canApply(advisor, targetClass, false);

}

 

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {

 if (advisor instanceof IntroductionAdvisor) {

  return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);

 }

 else if (advisor instanceof PointcutAdvisor) {

  PointcutAdvisor pca = (PointcutAdvisor) advisor;

  // pca是解析自定义事物标签时注入的BeanFactoryTransactionAttributeSourceAdvisor,Pointcut就是其内部的TransactionAttributeSourcePointcut

  return canApply(pca.getPointcut(), targetClass, hasIntroductions);

 }

 else {

  // It doesn't have a pointcut so we assume it applies.

  return true;

 }

}

 

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;

 }

 

 // pc是BeanFactoryTransactionAttributeSourceAdvisor属性TransactionAttributeSourcePointcut,TransactionAttributeSourcePointcut用到了注入的TransactionAttributeSource

 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 = null;

 if (methodMatcher instanceof IntroductionAwareMethodMatcher) {

  introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;

 }

 

 Set<Class<?>> classes = new LinkedHashSet<>();

 if (!Proxy.isProxyClass(targetClass)) {

  classes.add(ClassUtils.getUserClass(targetClass));

 }

 classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

 

 for (Class<?> clazz : classes) {

  Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);

  for (Method method : methods) {

   if (introductionAwareMethodMatcher != null ?

     introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :

     methodMatcher.matches(method, targetClass)) {

    return true;

   }

  }

 }

 

 return false;

}

 

3.3.2 基于事务注解获取事务属性 AnnotationTransactionAttributeSource

Spring5.x Transaction 自定义事务标签

 

读取Spring的JDK 1.5+ {@link Transactional}注解,封装成TransactionAttribute,并将相应的事务属性公开给Spring的事务基础结构。 还支持JTA 1.2的{@link javax.transaction.Transactional}和EJB3的{@link javax.ejb.TransactionAttribute}注解(如果存在)。 也可以用作自定义TransactionAttributeSource的基类,或通过{@link TransactionAnnotationParser}策略进行自定义。

 

3.3.2.1 置入TransactionAnnotationParser AnnotationTransactionAttributeSource

static {

 ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();

 jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader);

 ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader);

}

 

public AnnotationTransactionAttributeSource() {

 this(true);

}

 

public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {

 this.publicMethodsOnly = publicMethodsOnly;

 if (jta12Present || ejb3Present) {

  this.annotationParsers = new LinkedHashSet<>(4);

  this.annotationParsers.add(new SpringTransactionAnnotationParser());

  if (jta12Present) {

   this.annotationParsers.add(new JtaTransactionAnnotationParser());

  }

  if (ejb3Present) {

   this.annotationParsers.add(new Ejb3TransactionAnnotationParser());

  }

 }

 else {

  this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());

 }

}

 

3.3.2.2 获取事务属性 AbstractFallbackTransactionAttributeSource.getTransactionAttribute

// 获取指定方法调用的事务属性。如果未找到方法属性,则默认为方法所属类的事务属性。

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {

 if (method.getDeclaringClass() == Object.class) {

  return null;

 }

 

 // First, see if we have a cached value.

 Object cacheKey = getCacheKey(method, targetClass);

 TransactionAttribute cached = this.attributeCache.get(cacheKey);

 if (cached != null) {

  // Value will either be canonical value indicating there is no transaction attribute,

  // or an actual transaction attribute.

  if (cached == NULL_TRANSACTION_ATTRIBUTE) {

   return null;

  }

  else {

   return cached;

  }

 }

 else {

  // 查找指定方法的TransactionAttribute,不一定是方法上的注解

  TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);

  // Put it in the cache.

  if (txAttr == null) {

   this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);

  }

  else {

   // 返回给定方法的完全限定名称,包括完全限定的接口/类名称+“.” +方法名称。

   String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);

   if (txAttr instanceof DefaultTransactionAttribute) {

    ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);

   }

   if (logger.isTraceEnabled()) {

    logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);

   }

   this.attributeCache.put(cacheKey, txAttr);

  }

  return txAttr;

 }

}

 

3.3.2.3 查找事务属性 AbstractFallbackTransactionAttributeSource.computeTransactionAttribute

对于事务属性获取规则:如果方法中存在事务属性,则使用方法上的事物属性,否则使用方法所在的类上的属性;如果方法所在类的属性上还是没有搜寻到对应的事务属性,那么再搜寻接口中的方法,再没有的话,最后尝试搜寻接口的类上面的声明。

// 查找指定方法的TransactionAttribute,不一定是方法上的注解

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {

 // 禁止非Public方法获取TransactionAttribute。

 if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {

  return null;

 }

 

 //该方法可能在接口上,但是我们需要目标类的属性。 如果目标类为null,则该方法将保持不变。method接口中的方法,specificMethod实现类中的方法。

 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;

 }

 

 // 方法是接口定义的

 if (specificMethod != method) {

  // 接口的方法中是否存在事务声明

  txAttr = findTransactionAttribute(method);

  if (txAttr != null) {

   return txAttr;

  }

  // 接口是否存在事务声明

  txAttr = findTransactionAttribute(method.getDeclaringClass());

  if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {

   return txAttr;

  }

 }

 

 return null;

}

 

3.3.2.4 查找事务属性 AnnotationTransactionAttributeSource.findTransactionAttribute

protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {

 return determineTransactionAttribute(clazz);

}

 

@Override

@Nullable

protected TransactionAttribute findTransactionAttribute(Method method) {

 return determineTransactionAttribute(method);

}

 

// 确定给定方法或类的事务属性。 此实现委派了已配置的{@link TransactionAnnotationParser SpringTransactionAnnotationParsers} ,用于将已知的注释解析为Spring的元数据属性类。 如果不是事务型,则返回{@code null}。

@Nullable

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {

 // AnnotationTransactionAttributeSource实例化时往this.annotationParsers中默认加入了SpringTransactionAnnotationParser

 for (TransactionAnnotationParser annotationParser : this.annotationParsers) {

  TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);

  if (attr != null) {

   return attr;

  }

 }

 return null;

}

 

3.3.3 事务拦截器 TransactionInterceptor

3.3.3.1 执行调用 invokeWithinTransaction

public Object invoke(MethodInvocation invocation) throws Throwable {

 // 可能是{@code null},transactionAttributeSource应该传递给目标类以及方法(可能来自接口)。

 Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

 

 // Adapt to TransactionAspectSupport's invokeWithinTransaction...

 return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);

}

 

(1) 通过TransactionAttributeSource获取TransactionAttribute

(2) 获取PlatformTransactionManager

(3) 生成方法唯一标识

(4) 判断是声明式事务还是编程式事务

声明式事务:

创建TransactionInfo并绑定到当前线程

执行被增强方法

如果执行异常则走异常处理分支

清楚事务信息

提交事务

 

编程式事务:

创建TransactionInfo并绑定到当前线程

执行被增强方法

清楚事务信息

 

 

TransactionAspectSupport

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,

  final InvocationCallback invocation) throws Throwable {

 // 如果事物属性为null,则该方法为非事务处理

 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)) {

  // 创建新的TransactionInfo并绑定到当前线程

  TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);

 

  Object retVal;

  try {

   // 环绕增强:拦截器链中的下一个拦截器,通常,这将导致目标对象被调用。

   retVal = invocation.proceedWithInvocation();

  }

  catch (Throwable ex) {

   // 处理异常:提交或回滚

   completeTransactionAfterThrowing(txInfo, ex);

   throw ex;

  }

  finally {

   // 清空事务信息

   cleanupTransactionInfo(txInfo);

  }

  

  // 提交事务

  commitTransactionAfterReturning(txInfo);

  return retVal;

 }

 else {

  // 编程式事务 创建异常持有者

  final ThrowableHolder throwableHolder = new ThrowableHolder();

 

  // 这是一个CallbackPreferringPlatformTransactionManager:传入一个TransactionCallback。

  try {

   Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> {

    // 创建事务信息

    TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

    try {

     return invocation.proceedWithInvocation();

    }

    catch (Throwable ex) {

     if (txAttr.rollbackOn(ex)) {

      // RuntimeException:将导致回滚。

      if (ex instanceof RuntimeException) {

       throw (RuntimeException) ex;

      }

      else {

       throw new ThrowableHolderException(ex);

      }

     }

     else {

      // 正常的返回值:将导致提交。

      throwableHolder.throwable = ex;

      return null;

     }

    }

    finally {

//  清空事务信息

     cleanupTransactionInfo(txInfo);

    }

   });

 

   // 检查结果状态:它可能指示要抛出的Throwable。

   if (throwableHolder.throwable != null) {

    throw throwableHolder.throwable;

   }

   return result;

  }

  catch (ThrowableHolderException ex) {

   throw ex.getCause();

  }

  catch (TransactionSystemException ex2) {

    // 应用程序异常被提交异常覆盖

   if (throwableHolder.throwable != null) {

    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);

    ex2.initApplicationException(throwableHolder.throwable);

   }

   throw ex2;

  }

  catch (Throwable ex2) {

   // 应用程序异常被提交异常覆盖

   if (throwableHolder.throwable != null) {

    logger.error("Application exception overridden by commit exception", throwableHolder.throwable);

   }

   throw ex2;

  }

 }

}

 

3.3.3.2 获取事物管理器 determineTransactionManager

获取事物管理器流程

(1) 如果未设置事物属性,直接返回TransactionAspectSupport.transactionManager

(2) 事物属性存在qualifier或TransactionAspectSupport.transactionManagerBeanName存在,获取指定的事务管理器

(3) 不获取指定的事务管理器,直接返回TransactionAspectSupport.transactionManager,不存在从缓存中获取

(4) 如果缓存中不存在则从容器中获取类型为PlatformTransactionManager的Bean

 

protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {

 // 如果未设置事物属性,请勿尝试查找事物管理器,返回TransactionAspectSupport.transactionManager

 if (txAttr == null || this.beanFactory == null) {

  return getTransactionManager();

 }

 

 String qualifier = txAttr.getQualifier();

 if (StringUtils.hasText(qualifier)) {

  // 获取qualifier指定的事务管理器

  return determineQualifiedTransactionManager(this.beanFactory, qualifier);

 }

 else if (StringUtils.hasText(this.transactionManagerBeanName)) {

  // 获取this.transactionManagerBeanName指定的事务管理器

  return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);

 }

 else {

  // 返回TransactionAspectSupport.transactionManager

  PlatformTransactionManager defaultTransactionManager = getTransactionManager();

  if (defaultTransactionManager == null) {

   // 从缓存中获取,如果不存在则从容器中获取类型为PlatformTransactionManager的Bean

   defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);

   if (defaultTransactionManager == null) {

    defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);

    this.transactionManagerCache.putIfAbsent(

      DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);

   }

  }

  return defaultTransactionManager;

 }

}

 

// 获取指定名称的事务管理器并缓存起来

private PlatformTransactionManager determineQualifiedTransactionManager(BeanFactory beanFactory, String qualifier) {

 PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);

 if (txManager == null) {

  txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(

    beanFactory, PlatformTransactionManager.class, qualifier);

  this.transactionManagerCache.putIfAbsent(qualifier, txManager);

 }

 return txManager;

}

 

3.3.3.3 生成方法唯一标识 methodIdentification

private String methodIdentification(Method method, @Nullable Class<?> targetClass,

  @Nullable TransactionAttribute txAttr) {

 

 String methodIdentification = methodIdentification(method, targetClass);

 if (methodIdentification == null) {

  if (txAttr instanceof DefaultTransactionAttribute) {

   methodIdentification = ((DefaultTransactionAttribute) txAttr).getDescriptor();

  }

  if (methodIdentification == null) {

   methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);

  }

 }

 return methodIdentification;

}

 

@Nullable

protected String methodIdentification(Method method, @Nullable Class<?> targetClass) {

 return null;

}

 

3.3.3.4 创建事务信息 createTransactionIfNecessary

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,

  @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

 

 // 如果未指定事务名称,则将方法标识用作事务名称。

 if (txAttr != null && txAttr.getName() == null) {

  txAttr = new DelegatingTransactionAttribute(txAttr) {

   @Override

   public String getName() {

    return joinpointIdentification;

   }

  };

 }

 

 TransactionStatus status = null;

 if (txAttr != null) {

  if (tm != null) {

   // 根据事务属性中指定的传播行为,返回当前活动的事务或创建新的事务。

   status = tm.getTransaction(txAttr);

  }

  else {

   if (logger.isDebugEnabled()) {

    logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +

      "] because no transaction manager has been configured");

   }

  }

 }

 return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

}

 

3.3.3.5 创建事务信息 TransactionInfo

// 为给定的事务属性和状态对象创建一个TransactionInfo,事务属性(txAttr)是否为NULL决定方法是否是事务性

protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,

  @Nullable TransactionAttribute txAttr, String joinpointIdentification,

  @Nullable TransactionStatus status) {

 

 TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);

 if (txAttr != null) {

  // 方法需要事务

  if (logger.isTraceEnabled()) {

   logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");

  }

  // 如果已经存在不兼容的事务,事务管理器将标记错误。TransactionInfo.hasTransaction()方法将返回true。《Spring5.X 事务管理器 PlatformTransactionManager》

  txInfo.newTransactionStatus(status);

 }

 else {

  // 方法不需要事务,TransactionInfo.hasTransaction()方法将返回false。我们仅创建它以保持此类中维护的ThreadLocal堆栈的完整性。

  if (logger.isTraceEnabled()) {

   logger.trace("No need to create transaction for [" + joinpointIdentification +

     "]: This method is not transactional.");

  }

 }

 

 // 我们始终将TransactionInfo绑定到线程,即使我们没有在此处创建新的事务。这保证即使此方面未创建任何事务,也将正确管理TransactionInfo堆栈

 txInfo.bindToThread();

 return txInfo;

}

 

3.3.3.6 异常处理 completeTransactionAfterThrowing

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {

 // 事务信息存在事务状态(根据事务属性从事务管理器中获取的,传送门3.3.4.4)

 if (txInfo != null && txInfo.getTransactionStatus() != null) {

  if (logger.isTraceEnabled()) {

   logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +

     "] after exception: " + ex);

  }

  

   // 当前异常是执行事务回滚的异常

  if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {

   try {

    txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());

   }

   catch (TransactionSystemException ex2) {

    logger.error("Application exception overridden by rollback exception", ex);

    ex2.initApplicationException(ex);

    throw ex2;

   }

   catch (RuntimeException | Error ex2) {

    logger.error("Application exception overridden by rollback exception", ex);

    throw ex2;

   }

  }

  else {

   // 如果TransactionStatus.isRollbackOnly()为true,仍将回滚。

   try {

    txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());

   }

   catch (TransactionSystemException ex2) {

    logger.error("Application exception overridden by commit exception", ex);

    ex2.initApplicationException(ex);

    throw ex2;

   }

   catch (RuntimeException | Error ex2) {

    logger.error("Application exception overridden by commit exception", ex);

    throw ex2;

   }

  }

 }

}

 

3.3.3.7 清除事务信息 cleanupTransactionInfo

protected void cleanupTransactionInfo(@Nullable TransactionInfo txInfo) {

if (txInfo != null) {

   // 调用TransactionInfo.restoreThreadLocalStatus

  txInfo.restoreThreadLocalStatus();

 }

}

 

TransactionInfo

private void bindToThread() {

  // 公开当前的TransactionStatus,并保留所有现有的TransactionStatus,以便在此事务完成后进行恢复。

  this.oldTransactionInfo = transactionInfoHolder.get();

  transactionInfoHolder.set(this);

 }

 

 private void restoreThreadLocalStatus() {

  // 使用堆栈还原旧的事务TransactionInfo。 如果未设置,则为null。

  transactionInfoHolder.set(this.oldTransactionInfo);

 }

 

3.3.3.8 提交事务 commitTransactionAfterReturning

// 在成功完成调用之后执行,但是在处理异常之后不执行。 如果我们不创建事务,则不执行任何操作。

protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {

 if (txInfo != null && txInfo.getTransactionStatus() != null) {

  if (logger.isTraceEnabled()) {

   logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");

  }

  txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());

 }

}

 

3.3.4 注册类型为BeanFactoryTransactionAttributeSourceAdvisor的Bean

Spring5.x Transaction 自定义事务标签

 

3.3.4.1 BeanFactoryTransactionAttributeSourceAdvisor

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

@Nullable

private TransactionAttributeSource transactionAttributeSource;

 

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {

 @Override

 @Nullable

 protected TransactionAttributeSource getTransactionAttributeSource() {

  return transactionAttributeSource;

 }

};

}

 

3.3.4.2 TransactionAttributeSourcePointcut

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

 

@Override

public boolean matches(Method method, Class<?> targetClass) {

 if (TransactionalProxy.class.isAssignableFrom(targetClass) ||

   PlatformTransactionManager.class.isAssignableFrom(targetClass) ||

   PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {

  return false;

 }

 TransactionAttributeSource tas = getTransactionAttributeSource();

 // 传送门 3.3.3.1

 return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);

}

 

// 获取基础的TransactionAttributeSource(可以为{@code null})。 由子类实现。

@Nullable

protected abstract TransactionAttributeSource getTransactionAttributeSource();

}