Spring源码分析九:事务原理源码分析

文章目录

  • (一)spring事务入口
  • (二)Spring事务切入方式
    • 2.1 InfrastructureAdvisorAutoProxyCreator自动代理器
      • 2.1.1 InfrastructureAdvisorAutoProxyCreator层级示意图
      • 2.1.2 获取增强器getAdvicesAndAdvisorsForBean
        • 2.1.2.1 获取增强器findCandidateAdvisors
        • 2.1.2.2 匹配增强器findAdvisorsThatCanApply
        • 2.2.2.3 事务标签提取
        • 2.1.2.4 解析事务标签(核心)
      • 2.1.3 事务增强器(事务实现原理)
        • 2.1.3.1 创建事务createTransactionIfNecessary
        • 2.1.3.2 回滚处理——completeTransactionAfterThrowing
          • 2.1.3.2.1 回滚条件
          • 2.1.3.2.2 回滚处理——rollback
        • 2.1.3.3 回滚后清除——cleanupAfterCompletion
        • 2.1.3.3 事务提交——commitTransactionAfterReturning

(一)spring事务入口

通常Spring事务开启是从配置文件或Springboot类型的注解模式,本次主要是分析xml配置文件类型的事务,开启入口为:
TxNamespaceHandler类开启事务:

public void init() {
    registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
    registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());//tx事务开启入口
    registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}

spring容器解析时,遇到该配置会使用AnnotationDrivenBeanDefinitionParser类中的parse方法进行解析:,parse方法会对该标签属性逐个解析配置,如事务切入方式mode="aspectj"或"proxy"属性。Spring默认切入方式为代理proxy,可通过mode属性指定事务支持方式。

public BeanDefinition parse(Element element, ParserContext parserContext) {
    registerTransactionalEventListenerFactory(parserContext);
    String mode = element.getAttribute("mode");//事务切入方式处理
    if ("aspectj".equals(mode)) {
        // spring aop模式切入方式 mode="aspectj"
        registerTransactionAspect(element, parserContext);
        if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
            registerJtaTransactionAspect(element, parserContext);
        }
    } else {
        // spring默认事务切入方式:代理 mode="proxy"
        AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
    }
    return null;
}

(二)Spring事务切入方式

Spring默认的事务切入方式:AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);主要针对这行代码开始展开,先讲下该行代码中的处理逻辑。
核心逻辑思想:

  • (1) AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);是否需要注册InfrastructureAdvisorAutoProxyCreator事务自动代理器bean;
  • (2)创建三个bean,分别为TransactionAttributeSource类型的bean即sourceDef、TransactionInterceptor类型的bean即interceptorDef和TransactionAttributeSourceAdvisor类型的bean即advisorDef;
  • (3)将前面两个bean即sourceDef、interceptorDef分别以transactionAttributeSource和adviceBeanName属性注入到第三个bean即advisorDef中;
  • (4)将第三个bean即advisorDef注册到TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor"类型的bean中并注册到容器中。

逻辑示意图:

Spring源码分析九:事务原理源码分析_第1张图片

具体实现代码如下:

private static class AopAutoProxyConfigurer {
    
    public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
        // 创建事务自动代理器 InfrastructureAdvisorAutoProxyCreator,使用该类作为名为AUTO_PROXY_CREATOR_BEAN_NAME的bean自动代理器
        AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
        // TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor",创建此类型的bean
        String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
        if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {//容器中不包含该类型的bean时则创建
            Object eleSource = parserContext.extractSource(element);

            // 创建 TransactionAttributeSource 类型的bean即BeanDefinition
            RootBeanDefinition sourceDef = new RootBeanDefinition(
                "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
            sourceDef.setSource(eleSource);
            sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            // 注册到spring中时使用,利用spring生成beanName的规则生成 TransactionAttributeSource 的bean名称
            String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

            // 创建 TransactionInterceptor 类型的bean即BeanDefinition
            RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
            interceptorDef.setSource(eleSource);
            interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            registerTransactionManager(element, interceptorDef);
            interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
            // 注册到spring中时使用,利用spring生成beanName的规则生成 TransactionInterceptor 的bean名称
            String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
            
            // 创建 TransactionAttributeSourceAdvisor 类型的bean即BeanDefinition
            RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
            advisorDef.setSource(eleSource);
            advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
            // 将sourceName类型的bean注入到advisorDef的属性transactionAttributeSource中
            advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
            // 将interceptorName类型的bean注入到advisorDef的属性adviceBeanName中
            advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
            // 该标签是否配置了oder属性,处理该排序属性
            if (element.hasAttribute("order")) {
                advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
            }
            // 将生成的advisorDef的bean作为txAdvisorBeanName类型的bean的值注册到容器中
            parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
            // 创建CompositeComponentDefinition类型的bean即BeanDefinition
            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);//将其注册到容器中
        }
    }
}

AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);是注册事务代理器的入口,委托给AopNamespaceUtils进行封装,spring很多小功能细节都是交于其他类辅助实现,高度体现函数的封装性,也是优秀框架的方面之一,下面开始深入分析事务代理器,逻辑如下:

public static void registerAutoProxyCreatorIfNecessary(
			ParserContext parserContext, Element sourceElement) {
    BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
        parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    registerComponentIfNecessary(beanDefinition, parserContext);
}

委托AopConfigUtils->registerAutoProxyCreatorIfNecessary来注册自动代理器,其中使用InfrastructureAdvisorAutoProxyCreator.class作为事务代理器,最后在spring容器中使用registerOrEscalateApcAsRequired判断是否存在自动代理器,并决定是否采用InfrastructureAdvisorAutoProxyCreator覆盖已存在的代理器,如果不存在,则创建自动代理器的bean进行注册到容器中,bean类型为AUTO_PROXY_CREATOR_BEAN_NAME即org.springframework.aop.config.internalAutoProxyCreator

public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
        parserContext.getRegistry(), parserContext.extractSource(sourceElement));//调用内部事务自动代理器
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    registerComponentIfNecessary(beanDefinition, parserContext);
}
// InfrastructureAdvisorAutoProxyCreator 自动代理器来实现事务
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    // 检测AUTO_PROXY_CREATOR_BEAN_NAME 自动代理器bean是否已被注册
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        // 获取自动代理器BeanDefinition
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        // 判断beanName是否一致
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            // 优先级比较,谁的优先级大就使用谁作为自动代理器的class
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }
    // 此处代码逻辑是在容器不存在自动代理器时创建自动代理器并使用InfrastructureAdvisorAutoProxyCreator作为其bean的实现类
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

2.1 InfrastructureAdvisorAutoProxyCreator自动代理器

2.1.1 InfrastructureAdvisorAutoProxyCreator层级示意图

Spring源码分析九:事务原理源码分析_第2张图片

InfrastructureAdvisorAutoProxyCreator间接继承了AbstractAutoProxyCreator,AbstractAutoProxyCreator直接实现了SmartInstantiationAwareBeanPostProcessor接口,间接实现了InstantiationAwareBeanPostProcessor接口和BeanPostProcessor接口,那么Spring中的bean在初始化后会调用初始化后方法postProcessAfterInitialization,该方法在父类AbstractAutoProxyCreator中实现。
AbstractAutoProxyCreator->postProcessAfterInitialization初始化后方法逻辑:

  1. 从缓存中获取bean进行匹配初始化后得到的bean是否一致(循环依赖时导致不一致),不一致则要深入的判断是否需要创建代理bean;
  2. 深入bean标记、属性过滤、基础设置类如beanFactory类型的bean等条件下不需要创建代理,其他条件则创建代理,先获取增强器,然后根据增强器创建代理bean。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        // 获取bean的缓存key,根据class和beanName推测出key
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 判断是否因为避免循环依赖而需要创建的代理,如果需要则创建并封装bean
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);//封装bean
        }
    }
    return bean;
}
// 经过属性配置、处理标记、基础设置类控制验证后,如果符合条件则直接返回bean,否则创建代理bean返回
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 该beanName、cacheKey、bean是否已经被标记为处理过,如果处理过则直接返回原bean
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 是否是基础设施类或配置忽略,如果是则忽略
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 根据指定bean获取对应的增强器,下面详细分析
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 根据增强器去创建代理bean
        Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

2.1.2 获取增强器getAdvicesAndAdvisorsForBean

基于wrapIfNecessary中创建代理bean的前提:先获取增强器即getAdvicesAndAdvisorsForBean方法由AbstractAdvisorAutoProxyCreator类负责实现,核心逻辑如下:

  • (1)获取增强器即findCandidateAdvisors方法;
  • (2)匹配bean与增强器即findAdvisorsThatCanApply;
protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    //高度封装具体细节,交由findEligibleAdvisors来实现获取和匹配工作
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}
2.1.2.1 获取增强器findCandidateAdvisors

先来看一下TransactionAttributeSourceAdvisor层级图,在注册三个bean时,其中有一个bean类型为TransactionAttributeSourceAdvisor,的确是实现了Advisor接口,如下:
Spring源码分析九:事务原理源码分析_第3张图片

findCandidateAdvisors获取增强器代码逻辑:

  • (1)从缓存或spring容器中获取实现了Advisor接口的所有增强器bean;
  • (2)遍历所有增强器,满足isEligibleBean方法(重写时可能改变Boolean值)设置和isCurrentlyInCreation验证(是否正在创建中)的存储在advisors中作为获取增强器的结果;
protected List<Advisor> findCandidateAdvisors() {
    // 验证advisorRetrievalHelper强制有值 
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
    // 从缓存中直接获取增强器
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 从Spring容器中获取增强器Advisor
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
        // 缓存该值
        this.cachedAdvisorBeanNames = advisorNames;
    }
    if (advisorNames.length == 0) {
        return new ArrayList<>();
    }

    // 遍历容器中实现了Advisor接口的所有bean,在事务启动标签annotation-driven中时曾注入过三个bean,如TransactionAttributeSourceAdvisor
    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Skipping currently created advisor '" + name + "'");
                }
            } else {
                try {
                    // 获取实现了Advisor接口的bean
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                } catch (BeanCreationException ex) {
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        String bceBeanName = bce.getBeanName();
                        if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                            if (logger.isTraceEnabled()) {
                                logger.trace("Skipping advisor '" + name +
                                             "' with dependency on currently created bean: " + ex.getMessage());
                            }
                            continue;
                        }
                    }
                    throw ex;
                }
            }
        }
    }
    return advisors;
}
2.1.2.2 匹配增强器findAdvisorsThatCanApply

整体匹配逻辑:

  • (1)先后使用ThreadLocal存储线程变量即currentProxiedBeanName变量存储beanName;
  • (2)委托于抽象类AopUtils负责匹配增强器,其中先处理引介增强和普通增强,最后使用三个重载方法canApply分别对应不同场景来匹配,实际上就是为了匹配TransactionAttributeSourceAdvisor增强器;
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    // 设置当前匹配的beanName,currentProxiedBeanName变量存储,类型为ThreadLocal
    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    } finally {
        // 清空currentProxiedBeanName变量值
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}
// 委托于抽象类AopUtils负责匹配增强器
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    for (Advisor candidate : candidateAdvisors) {
        // 先处理引介增强和重载canApply
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    for (Advisor candidate : candidateAdvisors) {
        // 略过引介增强
        if (candidate instanceof IntroductionAdvisor) {
            // already processed
            continue;
        }
        // 处理普通增强器
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

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) { // TransactionAttributeSourceAdvisor 实现了PointcutAdvisor接口,满足此条件
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        // pca.getPointcut() 方法返回的是TransactionAttributeSource的实例
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    } else {
        // It doesn't have a pointcut so we assume it applies.
        return true;
    }
}

// 该方法尤为重要,前面两个重载方法,当事务TransactionAttributeSourceAdvisor增强器被匹配到时,会调用canApply三参数方法去匹配目标类和类中的所有方法
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;
    }
    // 获取的是TransactionAttributeSourcePointcut类型的对象,该对象是TransactionAttributeSourceAdvisor类的内部成员变量即pointcut成员变量
    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) {
            // matches 方法匹配,涉及到事务标签提取,下面第三点中详细分析
            if (introductionAwareMethodMatcher != null ? 
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }
    return false;
}
2.2.2.3 事务标签提取

findAdvisorsThatCanApply匹配增强器中提到matches方法,该matches是由TransactionAttributeSourcePointcut实例对象调用,tas.getTransactionAttribute(method, targetClass) != null此代码为BeanFactoryTransactionAttributeSourceAdvisor内部成员变量pointcut调用TransactionAttributeSourcePointcut类中的方法,主要核心逻辑和代码逻辑如下:

提取事务标签逻辑:

  1. 获取spring初始化加载的TransactionAttributeSource类型的bean即对象tas,然后紧接着是获取事务声明getTransactionAttribute;
  2. 先从缓存getCacheKey中获取事务声明;
  3. 缓存中没有则提取事务声明,分为实现类中方法事务声明、实现类级别事务声明、接口中方法事务声明和接口级别事务声明四种类型,满足任意一种即可,优先级为上述顺序;
    说明:获取事务时方法必须为公共修饰符类型,否则事务失效。

事务逻辑提取代码:

public boolean matches(Method method, Class<?> targetClass) {
   TransactionAttributeSource tas = getTransactionAttributeSource();// 返回的是TransactionAttributeSource对象
    // getTransactionAttribute方法为BeanFactoryTransactionAttributeSourceAdvisor内部成员变量pointcut调用TransactionAttributeSourcePointcut类中的方法
   return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

// TransactionAttributeSourcePointcut 中的获取事务属性方法
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }

    // 第一步从缓存中获取
    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 txAttr = computeTransactionAttribute(method, targetClass);
        // 缓存事务提取结果
        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;
    }
}

/**
 * 提取事务声明步骤:
 * (1)首先必须是公共方法
 * (2)然后去实现类中的方法中获取事务声明
 * (3)实现类级别获取事务声明
 * (4)接口中的方法获取事务声明
 * (5)接口类级别中获取事务声明
 */

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	// 非公共方法则事务失效
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return 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;
}
2.1.2.4 解析事务标签(核心)

经过前面定义的事务逻辑提取框架定义的事务四个步骤:即实现类方法、实现类、接口方法、接口级别中比较核心的是如何解析事务标签,分别委托给AnnotationTransactionAttributeSource类和SpringTransactionAnnotationParser类去完成事务注解、事务的所有属性提取工作;

主要逻辑:

  1. AnnotationTransactionAttributeSource类负责遍历annotationParsers解析器,去调用SpringTransactionAnnotationParser中解析事务标签中的属性;
  2. SpringTransactionAnnotationParser类负责提取事务注解Transactional和事务的所有属性提取,最后封装为TransactionAttribute对象返回(实际为RuleBasedTransactionAttribute类型);

提取逻辑:

// AnnotationTransactionAttributeSource类负责寻找事务标签属性
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
    // 查找细节委托给determineTransactionAttribute方法
    return determineTransactionAttribute(clazz);
}
// 根据element去解析TransactionAttribute事务属性
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    for (TransactionAnnotationParser parser : this.annotationParsers) {
        // SpringTransactionAnnotationParser类中的解析方法parseTransactionAnnotation,真正意义上的解析事务属性
        TransactionAttribute attr = parser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

/**
 * SpringTransactionAnnotationParser类中的解析方法parseTransactionAnnotation
 * (1)获取指定element级别中Transactional注解即事务声明;
 * (2)对获取到事务注解的AnnotationAttributes对象进行事务属性提取如propagation、isolation、timeout、readOnly、rollbackFor等
 */
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
        element, Transactional.class, false, false);
    if (attributes != null) {
        return parseTransactionAnnotation(attributes);
    } else {
        return null;
    }
}

// 根据Trasactional标签或注解去解析事务中的属性propagation、isolation、readOnly、rollbackForClassName等
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
    Propagation propagation = attributes.getEnum("propagation");// 解析 propagation
    rbta.setPropagationBehavior(propagation.value());
    Isolation isolation = attributes.getEnum("isolation");// 解析 isolation
    rbta.setIsolationLevel(isolation.value());
    rbta.setTimeout(attributes.getNumber("timeout").intValue());// 解析 timeout
    rbta.setReadOnly(attributes.getBoolean("readOnly"));// 解析 readOnly
    rbta.setQualifier(attributes.getString("value"));// 解析 value
    List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
    for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
        rollbackRules.add(new RollbackRuleAttribute(rbRule));// 解析 rollbackFor
    }
    for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
        rollbackRules.add(new RollbackRuleAttribute(rbRule));// 解析 rollbackForClassName
    }
    for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
        rollbackRules.add(new NoRollbackRuleAttribute(rbRule));// 解析 noRollbackFor
    }
    for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
        rollbackRules.add(new NoRollbackRuleAttribute(rbRule));// 解析 noRollbackForClassName
    }
    rbta.setRollbackRules(rollbackRules);
    return rbta;
}

至此,事务初始化工作基本完毕,但是还是值得一提的是,BeanFactoryTransactionAttributeSourceAdvisor 是 Advisor 的实现类,必须遵守 Advisor 的执行方法,当代理被调用时会调用这个类的增强犯法即bean的Advisor,因事务标签在解析时注册了三个bean,其中有一个 bean 为 TransactionInterceptor 类型的bean注入到了 BeanFactoryTransactionAttributeSourceAdvisor 中,即在调用事务增强器增强的代理类时会先执行 TransactionInterceptor 中的增强方法即 invoke 方法,该方法中完成了这个事务的逻辑。

2.1.3 事务增强器(事务实现原理)

TransactionInterceptor 拦截器作为实现事务的核心逻辑,相对来说是比较复杂的,TransactionInterceptor 是实现了 MethodInterceptor 拦截器接口,那么入口就是 invoke 方法,其主要包含spring两种事务支持方式:声明式事务编程式事务

  1. 获取事务属性;
  2. 加载配置中的TransactionManager;
  3. 声明式和编程式事务是不同逻辑处理;
  • (1)声明式事务时需要获取事务属性的,编程式事务不需要获取事务属性;
  • (2)TransactionManager在不同事务方式时处理不同,编程式事务使用CallbackPreferringPlatformTransactionManager作为回调接口类,其实现了PlatformTransactionManager该接口类,内部使用lamda接口方式执行回调方法;
  1. 在执行目标方法(拦截链proceedWithInvocation)前先调用createTransactionIfNecessary或prepareTransactionInfo先获取事务并设置事务信息如transactionManagertransactionAttributejoinpointIdentificationtransactionStatusoldTransactionInfo等;
  2. 执行目标方法即invocation.proceedWithInvocation();
  3. 执行过程中,若发生异常则进行回滚completeTransactionAfterThrowing(txInfo, ex);目前spring只支持RuntimeExceptionError异常回滚;
  4. 清除一些事务性的辅助信息即cleanupTransactionInfo(txInfo);
  5. 提交事务即commitTransactionAfterReturning(txInfo);
public Object invoke(MethodInvocation invocation) throws Throwable {
    // 获取目标类,该值可能为空,不为空时则将TransactionAttributeSource传递给目标类,也可能是来自接口中的方法
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    // 将方法、目标类等都以适配器模式进行传递实现
    return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
                                         final InvocationCallback invocation) throws Throwable {

    // 获取TransactionAttributeSource事务对象
    TransactionAttributeSource tas = getTransactionAttributeSource();
    // 获取事务属性
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    // 获取 beanFactory 中的 transactionManager
    final TransactionManager tm = determineTransactionManager(txAttr);
    // 事务管理器适配器校验
    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
        ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
            if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
                throw new TransactionUsageException(
                    "Unsupported annotated transaction on suspending function detected: " + method + ". Use TransactionalOperator.transactional extensions instead.");
            }
            ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
            if (adapter == null) {
                throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
            }
            return new ReactiveTransactionSupport(adapter);
        });
        return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
    }

    PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
    // 构建一个方法的唯一标识即全路径方法名
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    // 处理声明式事务
    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 创建事务TransactionInfo对象
        TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
        Object retVal;
        try {
            // 执行被增强的方法,该方法是环绕通知类型
            retVal = invocation.proceedWithInvocation();
        } catch (Throwable ex) {
            // 执行抛出异常的方法
            completeTransactionAfterThrowing(txInfo, ex);
            throw ex;
        } finally {
            // 清除一些辅助信息
            cleanupTransactionInfo(txInfo);
        }

        if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
            // Set rollback-only in case of Vavr failure matching our rollback rules...
            TransactionStatus status = txInfo.getTransactionStatus();
            if (status != null && txAttr != null) {
                retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
            }
        }
        // 提交事务
        commitTransactionAfterReturning(txInfo);
        return retVal;
    } else {
        // 处理编程式事务
        Object result;
        final ThrowableHolder throwableHolder = new ThrowableHolder();
        // 	
        try {
            result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
                // txInfo事务信息对象获取
                TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
                try {
                    Object retVal = invocation.proceedWithInvocation();
                    if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
                        retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
                    }
                    return retVal;
                } catch (Throwable ex) {
                    if (txAttr.rollbackOn(ex)) {
                        // A RuntimeException: will lead to a rollback.
                        if (ex instanceof RuntimeException) {
                            throw (RuntimeException) ex;
                        } else {
                            throw new ThrowableHolderException(ex);
                        }
                    } else {
                        // A normal return value: will lead to a commit.
                        throwableHolder.throwable = ex;
                        return null;
                    }
                } finally {
                    cleanupTransactionInfo(txInfo);
                }
            });
        } 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;
        }
        // Check result state: It might indicate a Throwable to rethrow.
        if (throwableHolder.throwable != null) {
            throw throwableHolder.throwable;
        }
        return result;
    }
}
2.1.3.1 创建事务createTransactionIfNecessary

概括一下主要事件:

  • (1)扩展事务属性:使用DelegatingTransactionAttribute来封装TransactionAttribute实例,txAttr.getName()默认在接口中是返回null,所以此处为DelegatingTransactionAttribute封装,提供更多的扩展功能;
  • (2)获取事务:通过PlatformTransactionManager来获取事务即tm.getTransaction(txAttr);参照Spring事务原理番外篇
  • (3)封装事务信息:封装TransactionInfo事务信息实例即prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

说明:其中txInfo.bindToThread();有使用到ThreadLocal来保存事务线程信息。

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {

    // 判断事务属性是否有设置名称,没有则使用DelegatingTransactionAttribute生成TransactionAttribute对象txAttr
    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) {
            // 获取事务TransactionStatus(核心,单独细讲)
            status = tm.getTransaction(txAttr);
        } else {
            if (logger.isDebugEnabled()) {
                logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
                             "] because no transaction manager has been configured");
            }
        }
    }
    // 根据上述txAttr、status、joinpointIdentification封装TransactionInfo
    return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}

//封装TransactionInfo
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, String joinpointIdentification,
			@Nullable TransactionStatus status) {
    TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);// 封装事务TransactionInfo
    if (txAttr != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
        }
        txInfo.newTransactionStatus(status);
    } else {
        if (logger.isTraceEnabled()) {
            logger.trace("No need to create transaction for [" + joinpointIdentification +
                         "]: This method is not transactional.");
        }
    }
    // 调用线程私有绑定 ThreadLocal
    txInfo.bindToThread();
    return txInfo;
}
private static final ThreadLocal<TransactionInfo> transactionInfoHolder = new NamedThreadLocal<>("Current aspect-driven transaction");
private void bindToThread() {
    // 线程绑定ThreadLocal
    this.oldTransactionInfo = transactionInfoHolder.get();
    transactionInfoHolder.set(this);
}
2.1.3.2 回滚处理——completeTransactionAfterThrowing
2.1.3.2.1 回滚条件
  • (1)对满足默认回滚条件的异常类型RuntimeException或Error进行回滚;(可自行扩展回滚条件如重写rollbackOn方法)
  • (2)对不满足回滚条件的义无反顾的提交事务;

说明:Spring默认回滚的异常条件为:RuntimeException或Error类型的异常;

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
    // 对存在的事务进行处理
    if (txInfo != null && txInfo.getTransactionStatus() != null) {
        if (logger.isTraceEnabled()) {
            logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
                         "] after exception: " + ex);
        }
        // 只处理默认的RuntimeException或Error类型的异常进行回滚
        if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                // 根据TransactionStatus信息进行回滚
                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 {
            // 不满足上述的回滚条件则仍然提交
            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;
            }
        }
    }
}
// 默认的回滚事务类型条件
public boolean rollbackOn(Throwable ex) {
    return (ex instanceof RuntimeException || ex instanceof Error);
}
2.1.3.2.2 回滚处理——rollback
  • (1)调用自定义触发器,包含回滚前——triggerBeforeCompletion()、回滚后——triggerAfterCompletion()调用,触发器也会对正常回滚、回滚过程中出现的异常进一步处理,而注册触发器是通过 TransactionSynchronizationManager 类中静态方法直接注册public static void registerSynchronization(TransactionSynchronization synchronization) throws IllegalStateException;
  • (2)回滚操作——doRollback(status);分为三种回滚,嵌入式事务回滚单独事务回滚JTA事务回滚标记;
    嵌入式事务回滚: 对于保存点事务的回滚主要是调用JDBC连接中的JdbcTransactionObjectSupport#rollbackToSavepoint方法回滚;
    单独事务回滚: 对于没有保存点的事务,直接回滚,Spring也是使用JDBC数据库连接中的DataSourceTransactionManager#doRollback方法回滚;
    JTA事务回滚: 当前存在事务,不属于上述嵌入式和单独事务时,则只做回滚标记,只能等到提交时作统一回滚;
public final void rollback(TransactionStatus status) throws TransactionException {
    // 对于已完成的事务,此时回滚会导致报错
		if (status.isCompleted()) {
			throw new IllegalTransactionStateException(
					"Transaction is already completed - do not call commit or rollback more than once per transaction");
		}
		DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
        // Spring 将回滚逻辑单独封装
		processRollback(defStatus, false);
	}

// 回滚逻辑单独封装
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
    try {
        boolean unexpectedRollback = unexpected;
        try {
            // 激活TransactionSynchronization中的triggerBeforeCompletion方法
            triggerBeforeCompletion(status);
            // 对于有保存点,将事务回滚到保存点
            if (status.hasSavepoint()) {
                if (status.isDebug()) {
                    logger.debug("Rolling back transaction to savepoint");
                }
                status.rollbackToHeldSavepoint();
            } else if (status.isNewTransaction()) {// 如果是新事务,则直接将该事务回滚
                if (status.isDebug()) {
                    logger.debug("Initiating transaction rollback");
                }
                doRollback(status);// 回滚当前事务
            } else {
                // 当前事务不是单独的事务,只能标记,等到事务链执行完毕后统一进行回滚
                if (status.hasTransaction()) {
                    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                        if (status.isDebug()) {
                            logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
                        }
                        // 打标记
                        doSetRollbackOnly(status);
                    } else {
                        if (status.isDebug()) {
                            logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
                        }
                    }
                } else {
                    logger.debug("Should roll back transaction but cannot - no transaction available");
                }
                // Unexpected rollback only matters here if we're asked to fail early
                if (!isFailEarlyOnGlobalRollbackOnly()) {
                    unexpectedRollback = false;
                }
            }
        } catch (RuntimeException | Error ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
        }
        // 激活TransactionSynchronization中的triggerAfterCompletion方法
        triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

        // Raise UnexpectedRollbackException if we had a global rollback-only marker
        if (unexpectedRollback) {
            throw new UnexpectedRollbackException(
                "Transaction rolled back because it has been marked as rollback-only");
        }
    } finally {
        // 清空记录的资源并将其挂起的资源进行恢复
        cleanupAfterCompletion(status);
    }
}
2.1.3.3 回滚后清除——cleanupAfterCompletion

当回滚操作执行完毕后,无论回滚成功、还是回滚失败,都需要在执行完毕后进行收尾工作,如下:

  • (1)设置事务完成状态,避免重复调用;
  • (2)如果当前事务时新的同步状态,需要将绑定到当前线程的事务信息清除;
  • (3)如果是新事务则需要释放资源;(Spring事务原理番外篇)
  • (4)如果执行该事务前有将其他事务挂起,则该事务结束后,需要唤醒被挂起的事务;
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
    status.setCompleted();// 设置完成状态 true
    // 同步事务清除
    if (status.isNewSynchronization()) {
        /** 清除同步保存的设置
            * synchronizations.remove();
            * currentTransactionName.remove();
            * currentTransactionReadOnly.remove();
            * currentTransactionIsolationLevel.remove();
            * actualTransactionActive.remove();
            */
        TransactionSynchronizationManager.clear();
    }
    // 单独事务清除
    if (status.isNewTransaction()) {
        /** 
         * (1)将当前线程中的数据库连接解除绑定;
         * (2)释放数据库连接、恢复数据库连接自动提交属性、重置数据库连接;
         * (3)如果当前事务是单独新创建,则需要立即释放数据库连接;
         */
        doCleanupAfterCompletion(status.getTransaction());
    }
    // 判断是否有被挂起的事务
    if (status.getSuspendedResources() != null) {
        if (status.isDebug()) {
            logger.debug("Resuming suspended transaction after completion of inner transaction");
        }
        Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
        // 唤醒挂起的事务
        resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
    }
}

protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
			throws TransactionException {
    if (resourcesHolder != null) {
        Object suspendedResources = resourcesHolder.suspendedResources;
        if (suspendedResources != null) {
            doResume(transaction, suspendedResources);// 唤醒
        }
        // 设置挂起的事务属性
        List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
        if (suspendedSynchronizations != null) {
            TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
            TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
            TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
            doResumeSynchronization(suspendedSynchronizations);
        }
    }
}
2.1.3.3 事务提交——commitTransactionAfterReturning

在事务提交前会进行判断,也就是嵌入式事务且无法设置保存点时,如果发生回滚,前面提到过三种回滚方式,如JTA方式是仅仅给了一个回滚标记,此时在这里将会发挥作用,当在commit提交时会进行判断该标记,若存在,则进行统一回滚;否则正常提交;

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());
    }
}
// 将事务提交操作封装,由AbstractPlatformTransactionManager类来实现
public final void commit(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {// 判断事务是否已完成,若完成还提交,则报异常
        throw new IllegalTransactionStateException(
            "Transaction is already completed - do not call commit or rollback more than once per transaction");
    }

    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    // 是否存在统一回滚标志
    if (defStatus.isLocalRollbackOnly()) {
        if (defStatus.isDebug()) {
            logger.debug("Transactional code has requested rollback");
        }
        // 直接回滚,false代表回滚标记
        processRollback(defStatus, false);
        return;
    }

    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
        if (defStatus.isDebug()) {
            logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
        }
        // 事务回滚,true代表仅回滚
        processRollback(defStatus, true);
        return;
    }
    // 事务提交,由事务原理番外篇细讲
    processCommit(defStatus);
}

因篇幅原因,关于事务提交processCommit(defStatus);具体实现请查阅Spring事务原理番外篇

你可能感兴趣的:(Spring源码分析,spring,java,spring,boot)