Spring Boot源码简析 事务管理

相关阅读

简介

本文主要介绍Spring Boot事务的配置解析和执行实现;

Demo

public class DemoService {

    @Transactional
    public void save() {
        // save
        throw new RuntimeException();
    }
}

如果save方法在执行过程中发生异常,且满足回滚要求(默认情况下RuntimeException满足事务回滚要求,可见DefaultTransactionAttribute.rollbackOn实现),那么发生异常前的数据库操作都会被回滚;

配置解析

Spring Boot事务核心功能主要由以下类实现:

  1. InfrastructureAdvisorAutoProxyCreator,为带有事务属性的方法创建代理;
  2. BeanFactoryTransactionAttributeSourceAdvisor,事务管理核心Advisor
  3. AnnotationTransactionAttributeSource,解析方法的事务属性;
  4. TransactionInterceptor,执行带有事务属性的方法;

Spring Boot支持两种配置方式:XML配置和注解配置,两种方式都会注册以上类型的Bean;
以上类型的Bean的功能详见注解配置

XML配置

配置文件

开始事务配置如下:

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

解析

annotation-driven标签的解析实现是在TxNamespaceHandler中配置,代码如下:

@Override
public void init() {
    registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
    registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
    registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}

可知,annotation-driven标签的解析由AnnotationDrivenBeanDefinitionParser完成,其parse方法用于解析该标签,实现如下:

public BeanDefinition parse(Element element, ParserContext parserContext) {
    this.registerTransactionalEventListenerFactory(parserContext);
    // annotation-driven 的mode属性支持aspectj和proxy
    String mode = element.getAttribute("mode");
    if ("aspectj".equals(mode)) {
        // 是aspectj模式
        this.registerTransactionAspect(element, parserContext);
        if (ClassUtils.isPresent("javax.transaction.Transactional", this.getClass().getClassLoader())) {
            this.registerJtaTransactionAspect(element, parserContext);
        }
    } else {
       // 否则就是proxy模式
       AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
    }

    return null;
}

private void registerTransactionAspect(Element element, ParserContext parserContext) {
    String txAspectBeanName = "org.springframework.transaction.config.internalTransactionAspect";
    String txAspectClassName = "org.springframework.transaction.aspectj.AnnotationTransactionAspect";
    
    // 注册org.springframework.transaction.config.internalTransactionAspect
    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 void registerJtaTransactionAspect(Element element, ParserContext parserContext) {
    String txAspectBeanName = "org.springframework.transaction.config.internalJtaTransactionAspect";
    String txAspectClassName = "org.springframework.transaction.aspectj.JtaAnnotationTransactionAspect";
    
    // 注册org.springframework.transaction.config.internalJtaTransactionAspect
    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 void registerAsyncExecutionAspect(Element element, ParserContext parserContext) {
    if (!parserContext.getRegistry().containsBeanDefinition(TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME)) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ASYNC_EXECUTION_ASPECT_CLASS_NAME);
        // 设置aspectOf属性
        builder.setFactoryMethod("aspectOf");
        // 设置executor属性
        String executor = element.getAttribute("executor");
        if (StringUtils.hasText(executor)) {
            builder.addPropertyReference("executor", executor);
        }
        // 设置exception-handler属性
        String exceptionHandler = element.getAttribute("exception-handler");
        if (StringUtils.hasText(exceptionHandler)) {
            builder.addPropertyReference("exceptionHandler", exceptionHandler);
        }
        // 注册org.springframework.scheduling.config.internalAsyncExecutionAspect
        parserContext.registerBeanComponent(new BeanComponentDefinition(builder.getBeanDefinition(),
                TaskManagementConfigUtils.ASYNC_EXECUTION_ASPECT_BEAN_NAME));
    }
}

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    // 注册InfrastructureAdvisorAutoProxyCreator如果需要的话
    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
    
    // 是否已注册org.springframework.transaction.config.internalTransactionAdvisor
    // 若已注册,则无需再注册
    if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
        Object eleSource = parserContext.extractSource(element);
        // 准备AnnotationTransactionAttributeSource
        RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
        sourceDef.setSource(eleSource);
        sourceDef.setRole(2);
        String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
        
        // 准备TransactionInterceptor
        RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
        interceptorDef.setSource(eleSource);
        interceptorDef.setRole(2);
        AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
        // 注入AnnotationTransactionAttributeSource
        interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
        
        // 准备BeanFactoryTransactionAttributeSourceAdvisor
        RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
        advisorDef.setSource(eleSource);
        advisorDef.setRole(2);
        // 注入AnnotationTransactionAttributeSource
        advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        // 注入TransactionInterceptor
        advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
        if (element.hasAttribute("order")) {
            advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
        }

        // 注册BeanFactoryTransactionAttributeSourceAdvisor BeanDefinition
        parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
        
        // 构建CompositeComponentDefinition完成以上Bean注册
        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);
    }
}

注解配置

注解的配置方式,主要是引入@EnableTransactionManagement注解,该注解的详细介绍可见:
Spring Boot源码简析 @EnableTransactionManagement

执行

TransactionInterceptor支撑了整个事务功能的架构,该类继承自TransactionAspectSupport,核心代码如下:

// TransactionInterceptor.java
public Object invoke(MethodInvocation invocation) throws Throwable {
    // 获取当前Bean的类型
    Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

    return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
        @Override
        @Nullable
        public Object proceedWithInvocation() throws Throwable {
            // 执行原始方法
            return invocation.proceed();
        }
        @Override
        public Object getTarget() {
            return invocation.getThis();
        }
        @Override
        public Object[] getArguments() {
            return invocation.getArguments();
        }
    });
}


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

    // 获取事务属性源
    TransactionAttributeSource tas = getTransactionAttributeSource();
    // 获取事务属性
    // 如果事务属性不存在,则该原始方法执行时不需要事务
    final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
    // 获取事务管理器
    // 如果事务属性指定事务管理器,则优先使用,否则使用默认事务管理器
    final TransactionManager tm = determineTransactionManager(txAttr);

    if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
        boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
        boolean hasSuspendingFlowReturnType = isSuspendingFunction &&
                COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName());
        if (isSuspendingFunction && !(invocation instanceof CoroutinesInvocationCallback)) {
            throw new IllegalStateException("Coroutines invocation not supported: " + method);
        }
        CoroutinesInvocationCallback corInv = (isSuspendingFunction ? (CoroutinesInvocationCallback) invocation : null);

        ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
            Class<?> reactiveType =
                    (isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType());
            ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
            if (adapter == null) {
                throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
                        method.getReturnType());
            }
            return new ReactiveTransactionSupport(adapter);
        });

        InvocationCallback callback = invocation;
        if (corInv != null) {
            callback = () -> CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
        }
        Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager) tm);
        if (corInv != null) {
            Publisher<?> pr = (Publisher<?>) result;
            return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow(pr) :
                    KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation()));
        }
        return result;
    }

    PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
    // 获取方法的唯一标识符
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    // 如果不存在事务属性,或者事务管理器不是CallbackPreferringPlatformTransactionManager类型
    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 标准的事务生命周期管理:getTransaction/commit/rollback

        // 创建事务信息,根据事务属性决定是否创建事务
        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)) {
            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 -> {
                // 准备事务信息
                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)) {
                        // RuntimeException可以触发事务回滚(DefaultTransactionAttribute实现)
                        // Spring框架认为Checked的异常属于业务的,coder需要处理
                        if (ex instanceof RuntimeException) {
                            throw (RuntimeException) ex;
                        }
                        else {
                            throw new ThrowableHolderException(ex);
                        }
                    }
                    else {
                        // 无需回滚,但因为发生异常,需要返回null
                        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;
        }

        if (throwableHolder.throwable != null) {
            // 存在异常则需要抛出
            throw throwableHolder.throwable;
        }
        return result;
    }
}

获取事务属性

TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);

事务属性配置

TransactionInterceptor是由ProxyTransactionManagementConfiguration配置器构建,在构建时注入AnnotationTransactionAttributeSource,代码如下:

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
    // 默认构建AnnotationTransactionAttributeSource
    return new AnnotationTransactionAttributeSource();
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    // 注入的TransactionAttributeSource默认为AnnotationTransactionAttributeSource
    interceptor.setTransactionAttributeSource(transactionAttributeSource);
    if (this.txManager != null) {
        interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
}

事务属性解析

所以tasAnnotationTransactionAttributeSource,其getTransactionAttribute(method, targetClass)实现继承自父类AbstractFallbackTransactionAttributeSource,代码如下:

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }

    // 已解析的结果会被缓存,故先尝试从缓存中获取,获取不到再进行解析
    // 缓存的Key就是方法的唯一标识符
    Object cacheKey = getCacheKey(method, targetClass);
    TransactionAttribute cached = this.attributeCache.get(cacheKey);
    if (cached != null) {
        // 缓存中存在,则直接使用缓存值

        // 缓存时对NULL值做特殊处理,此处需要转换为NULL值
        if (cached == NULL_TRANSACTION_ATTRIBUTE) {
            return null;
        }
        else {
            return cached;
        }
    }
    else {
        // 缓存中还不存在,那么就需要进行解析
        TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);

        // 缓存解析结果,方便下次使用
        if (txAttr == null) {
            // NULL值特殊处理,便于存储
            this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
        }
        else {
            String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
            if (txAttr instanceof DefaultTransactionAttribute) {
                // 针对DefaultTransactionAttribute的处理
                DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
                dta.setDescriptor(methodIdentification);
                dta.resolveAttributeStrings(this.embeddedValueResolver);
            }
            if (logger.isTraceEnabled()) {
                logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
            }
            this.attributeCache.put(cacheKey, txAttr);
        }
        return txAttr;
    }
}

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // 是否只允许public方法
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }

    // 找到该targetClass(如果存在的话)实现该method的Method
    // 如果method就是在targetClass中定义,或者targetClass没有重写method,那么specificMethod和method一致
    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;
}

protected abstract TransactionAttribute findTransactionAttribute(Class<?> clazz);

protected abstract TransactionAttribute findTransactionAttribute(Method method);

父类AbstractFallbackTransactionAttributeSource实现了解析事务属性的算法模板,将算法细节findTransactionAttribute(Class<?> clazz)findTransactionAttribute(Method method)留给子类去实现,AnnotationTransactionAttributeSource的实现如下:

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

protected TransactionAttribute findTransactionAttribute(Method method) {
    return determineTransactionAttribute(method);
}

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    // 遍历内部的事务注解解析器
    for (TransactionAnnotationParser parser : this.annotationParsers) {
        // 使用事务注解解析器解析方法或者类上的事务注解得到事务属性
        TransactionAttribute attr = parser.parseTransactionAnnotation(element);
        if (attr != null) {
            // 若解析得到事务属性,则直接返回使用,不再进行下一个
            return attr;
        }
    }
    return null;
}

用户可以指定TransactionAnnotationParser,默认值是在构建时设置的,代码如下:

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());
    }
}

最常用的就是SpringTransactionAnnotationParser,其parseTransactionAnnotation方法实现如下:

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    // 获取AnnotatedElement上的@Transactional注解
    AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
            element, Transactional.class, false, false);
    if (attributes != null) {
        // 存在Transactional注解,则转换为TransactionAttribute
        return parseTransactionAnnotation(attributes);
    }
    else {
        return null;
    }
}

/**
 * 将@Transactional的属性转换为TransactionAttribute
 */
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

    Propagation propagation = attributes.getEnum("propagation");
    rbta.setPropagationBehavior(propagation.value());
    Isolation isolation = attributes.getEnum("isolation");
    rbta.setIsolationLevel(isolation.value());

    rbta.setTimeout(attributes.getNumber("timeout").intValue());
    String timeoutString = attributes.getString("timeoutString");
    Assert.isTrue(!StringUtils.hasText(timeoutString) || rbta.getTimeout() < 0,
            "Specify 'timeout' or 'timeoutString', not both");
    rbta.setTimeoutString(timeoutString);

    rbta.setReadOnly(attributes.getBoolean("readOnly"));
    rbta.setQualifier(attributes.getString("value"));
    rbta.setLabels(Arrays.asList(attributes.getStringArray("label")));

    List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
    for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
        rollbackRules.add(new RollbackRuleAttribute(rbRule));
    }
    for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
        rollbackRules.add(new RollbackRuleAttribute(rbRule));
    }
    for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
        rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
    }
    for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
        rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
    }
    rbta.setRollbackRules(rollbackRules);

    return rbta;
}

创建事务

执行原始方法前,需要先创建事务(如果需要的话),代码如下:

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

    // 如果事务未指定name,那么使用方法的唯一标识符作为事务名称
    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);
}

PlatformTransactionManager tm会由determineTransactionManager确认,支持事务属性指定事务管理器,实现代码如下:

protected TransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
    // 如果不存在事务属性,那么不需要确保找到事务管理器
    // 如果BeanFactory不存在,那么只能选择默认事务管理器
    if (txAttr == null || this.beanFactory == null) {
        // 直接返回默认事务管理器,此时默认事务管理器可能未设置
        // 是在ProxyTransactionManagementConfiguration构建TransactionInterceptor时设置
        return getTransactionManager();
    }

    // 存在事务属性,则获取其指定的事务管理器若存在的话
    String qualifier = txAttr.getQualifier();
    if (StringUtils.hasText(qualifier)) {
        // 根据指定的BeanName从BeanFactory找到对应的事务管理器
        return determineQualifiedTransactionManager(this.beanFactory, qualifier);
    }
    else if (StringUtils.hasText(this.transactionManagerBeanName)) {
        // 如果设置了默认的事务管理器BeanName,则在BeanFactory中找到对应的事务管理器
        return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
    }
    else {
        // 使用默认的事务管理器
        TransactionManager defaultTransactionManager = getTransactionManager();
        if (defaultTransactionManager == null) {
            // 默认的事务管理器不存在,则尝试获取缓存中的事务管理器(如果之前获取到,那么就会被缓存,此时可以直接从缓存获取)
            defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
            if (defaultTransactionManager == null) {
                // 缓存中还不存在事务管理器,就从BeanFactory中找到任意一个事务管理器
                defaultTransactionManager = this.beanFactory.getBean(TransactionManager.class);
                // 缓存找到的事务管理器,方便下次直接使用
                this.transactionManagerCache.putIfAbsent(
                        DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
            }
        }
        return defaultTransactionManager;
    }
}

使用数据库时,我们使用的事务管理器一般都是DataSourceTransactionManager,其getTransaction(@Nullable TransactionDefinition definition)方法实现继承自父类AbstractPlatformTransactionManager,代码如下:

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
        throws TransactionException {

    // 使用默认值如果不存在事务属性的话
    TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());

    // 获取当前事务
    Object transaction = doGetTransaction();
    boolean debugEnabled = logger.isDebugEnabled();

    // 当前已经存在事务的处理
    if (isExistingTransaction(transaction)) {
        return handleExistingTransaction(def, transaction, debugEnabled);
    }

    // 事务超时校验
    if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
        throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
    }

    // 当前不存在事务

    // 事务传播属性设置为PROPAGATION_MANDATORY
    // 当前不存在事务就需要抛出异常
    if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
        throw new IllegalTransactionStateException(
                "No existing transaction found for transaction marked with propagation 'mandatory'");
    }
    // 事务传播属性设置为PROPAGATION_REQUIRED或者PROPAGATION_REQUIRES_NEW或者PROPAGATION_NESTED
    // 这些类型需要创建新事务
    else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
            def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
            def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        // 空挂起,因为当前不存在事务
        SuspendedResourcesHolder suspendedResources = suspend(null);
        if (debugEnabled) {
            logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
        }
        try {
            // 创建新事务
            return startTransaction(def, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error ex) {
            resume(null, suspendedResources);
            throw ex;
        }
    }
    // 事务传播属性设置为其它类型,即:PROPAGATION_SUPPORTS或者PROPAGATION_NOT_SUPPORTED或者PROPAGATION_NEVER
    // 这些类型不需要当前存在事务
    else {
        if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
            logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                    "isolation level will effectively be ignored: " + def);
        }
        // 空事务时是否需要事务同步,默认为SYNCHRONIZATION_ALWAYS,表示需要
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
    }
}

doGetTransaction()由子类DataSourceTransactionManager实现,代码如下:

protected Object doGetTransaction() {
    DataSourceTransactionObject txObject = new DataSourceTransactionObject();
    // 是否允许还原点
    txObject.setSavepointAllowed(isNestedTransactionAllowed());
    // 根据当前持有的数据源找到连接资源
    ConnectionHolder conHolder =
            (ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
    // 封装连接资源,false表示连接资源不是新创建的
    txObject.setConnectionHolder(conHolder, false);
    return txObject;
}

事务存在的判断由子类DataSourceTransactionManager实现,代码如下:

protected boolean isExistingTransaction(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    // 当前记录的连接不为空,且连接的事务有效
    return (txObject.hasConnectionHolder() && txObject.getConnectionHolder().isTransactionActive());
}

当前是否存在事务会影响后续逻辑,所以需要分两种情况处理;

当前已存在事务

处理逻辑如下:

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

    // 事务传播属性设置为PROPAGATION_NEVER,表示不需要事务,但此时存在事务,需要抛出异常
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
        throw new IllegalTransactionStateException(
                "Existing transaction found for transaction marked with propagation 'never'");
    }

    // 事务传播属性设置为PROPAGATION_NOT_SUPPORTED,表示不支持事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction");
        }
        // 挂起当前事务
        Object suspendedResources = suspend(transaction);
        boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
        // 准备事务状态,等本次操作结束后再恢复之前挂起事务
        return prepareTransactionStatus(
                definition, null, false, newSynchronization, debugEnabled, suspendedResources);
    }

    // 事务传播属性设置为PROPAGATION_REQUIRES_NEW,表示需要新事务
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
        if (debugEnabled) {
            logger.debug("Suspending current transaction, creating new transaction with name [" +
                    definition.getName() + "]");
        }
        // 挂起当前事务,当新事务结束后,再恢复当前事务
        SuspendedResourcesHolder suspendedResources = suspend(transaction);
        try {
            // 创建新事务
            return startTransaction(definition, transaction, debugEnabled, suspendedResources);
        }
        catch (RuntimeException | Error beginEx) {
            resumeAfterBeginException(transaction, suspendedResources, beginEx);
            throw beginEx;
        }
    }

    // 事务传播属性设置为PROPAGATION_NESTED,表示在当前事务下嵌套进行,支持还原点设置
    if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
        // 当前是否允许嵌套事务
        if (!isNestedTransactionAllowed()) {
            throw new NestedTransactionNotSupportedException(
                    "Transaction manager does not allow nested transactions by default - " +
                    "specify 'nestedTransactionAllowed' property with value 'true'");
        }
        if (debugEnabled) {
            logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
        }
        // 是否可以使用还原点
        if (useSavepointForNestedTransaction()) {
            DefaultTransactionStatus status =
                    prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
            // 创建还原点,这样嵌套事务异常可以不导致当前事务回滚
            status.createAndHoldSavepoint();
            return status;
        }
        else {
            // 不支持还原点设置的话,那么就需要创建新事务
            // JTA不支持还原点设置
            return startTransaction(definition, transaction, debugEnabled, null);
        }
    }

    // 此时,事务传播属性设置为PROPAGATION_SUPPORTS或者PROPAGATION_REQUIRED,表示可以在当前事务下进行

    if (debugEnabled) {
        logger.debug("Participating in existing transaction");
    }
    // 是否需要校验当前存在的事务
    if (isValidateExistingTransaction()) {
        // 校验当前事务

        if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
            Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
                Constants isoConstants = DefaultTransactionDefinition.constants;
                throw new IllegalTransactionStateException("Participating transaction with definition [" +
                        definition + "] specifies isolation level which is incompatible with existing transaction: " +
                        (currentIsolationLevel != null ?
                                isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
                                "(unknown)"));
            }
        }
        if (!definition.isReadOnly()) {
            if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
                throw new IllegalTransactionStateException("Participating transaction with definition [" +
                        definition + "] is not marked as read-only but existing transaction is");
            }
        }
    }
    // 获取事务同步标识
    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}

挂起事务实现如下:

protected final SuspendedResourcesHolder suspend(@Nullable Object transaction) throws TransactionException {
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
        // 当前线程存在事务同步信息

        // 缓存并挂起当前线程存在的事务同步信息
        List<TransactionSynchronization> suspendedSynchronizations = doSuspendSynchronization();
        try {
            Object suspendedResources = null;
            if (transaction != null) {
                // 挂起当前事务
                suspendedResources = doSuspend(transaction);
            }
            
            // 缓存并清空当前线程的事务同步管理器信息
            String name = TransactionSynchronizationManager.getCurrentTransactionName();
            TransactionSynchronizationManager.setCurrentTransactionName(null);
            boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
            TransactionSynchronizationManager.setCurrentTransactionReadOnly(false);
            Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
            TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(null);
            boolean wasActive = TransactionSynchronizationManager.isActualTransactionActive();
            TransactionSynchronizationManager.setActualTransactionActive(false);
            // 根据当前存在的事务信息、事务同步信息、事务同步管理器信息创建SuspendedResourcesHolder,便于后续恢复
            return new SuspendedResourcesHolder(
                    suspendedResources, suspendedSynchronizations, name, readOnly, isolationLevel, wasActive);
        }
        catch (RuntimeException | Error ex) {
            doResumeSynchronization(suspendedSynchronizations);
            throw ex;
        }
    }
    // 当前线程不存在事务同步信息
    else if (transaction != null) {
        // 直接挂起当前事务
        Object suspendedResources = doSuspend(transaction);
        // 根据当前存在的事务信息创建SuspendedResourcesHolder,便于后续恢复事务
        return new SuspendedResourcesHolder(suspendedResources);
    }
    else {
        // 无事务需挂起,则没必要缓存事务信息
        return null;
    }
}

准备事务状态实现如下:

protected final DefaultTransactionStatus prepareTransactionStatus(
        TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
        boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {
    
    // 基于已有的事务信息,构建事务状态
    DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, newTransaction, newSynchronization, debug, suspendedResources);
    // 准备事务同步信息
    prepareSynchronization(status, definition);
    return status;
}

protected DefaultTransactionStatus newTransactionStatus(
        TransactionDefinition definition, @Nullable Object transaction, boolean newTransaction,
        boolean newSynchronization, boolean debug, @Nullable Object suspendedResources) {

    // 是否开启新事务同步
    boolean actualNewSynchronization = newSynchronization &&
            !TransactionSynchronizationManager.isSynchronizationActive();
    return new DefaultTransactionStatus(
            transaction, newTransaction, actualNewSynchronization,
            definition.isReadOnly(), debug, suspendedResources);
}

/**
 * 将事务同步信息记录到当前线程中
 */
protected void prepareSynchronization(DefaultTransactionStatus status, TransactionDefinition definition) {
    if (status.isNewSynchronization()) {
        TransactionSynchronizationManager.setActualTransactionActive(status.hasTransaction());
        TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(
                definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT ?
                        definition.getIsolationLevel() : null);
        
        // 设置事务只读标识
        TransactionSynchronizationManager.setCurrentTransactionReadOnly(definition.isReadOnly());
        TransactionSynchronizationManager.setCurrentTransactionName(definition.getName());
        TransactionSynchronizationManager.initSynchronization();
    }
}

创建新事务实现如下:

private TransactionStatus startTransaction(TransactionDefinition definition, Object transaction,
        boolean debugEnabled, @Nullable SuspendedResourcesHolder suspendedResources) {

    boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
    // 构建事务状态
    DefaultTransactionStatus status = newTransactionStatus(
            definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
    // 开启新事务
    doBegin(transaction, definition);
    // 准备事务同步信息
    prepareSynchronization(status, definition);
    return status;
}

开启新事务的真正操作由子类DataSourceTransactionManager实现,代码如下:

protected void doBegin(Object transaction, TransactionDefinition definition) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
    Connection con = null;

    try {
        // 当前不存在连接资源,或者当前连接资源的事务同步标识为true,才需要创建新连接
        if (!txObject.hasConnectionHolder() ||
                txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
            // 创建新连接
            Connection newCon = obtainDataSource().getConnection();
            if (logger.isDebugEnabled()) {
                logger.debug("Acquired Connection [" + newCon + "] for JDBC transaction");
            }
            // 封装新连接资源,true表示连接资源是新创建的
            txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
        }

        // 设置连接资源和事务同步标识
        txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
        // 获取连接
        con = txObject.getConnectionHolder().getConnection();

        // 根据事务属性配置当前连接,比如:只读属性、隔离级别
        // 只针对当前连接
        Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
        txObject.setPreviousIsolationLevel(previousIsolationLevel);
        // 设置只读标识
        txObject.setReadOnly(definition.isReadOnly());

        // 如果连接是自动提交,则更改为由Spring手动提交
        if (con.getAutoCommit()) {
            txObject.setMustRestoreAutoCommit(true);
            if (logger.isDebugEnabled()) {
                logger.debug("Switching JDBC Connection [" + con + "] to manual commit");
            }
            con.setAutoCommit(false);
        }

        // 准备事务连接
        // 此处会根据数据库的enforceReadOnly标识和事务的只读标识,选择执行"SET TRANSACTION READ ONLY"
        prepareTransactionalConnection(con, definition);
        // 设置连接的事务有效标识
        // 判断当前线程是否存在事务会依赖该标识
        txObject.getConnectionHolder().setTransactionActive(true);

        // 设置事务超时信息
        int timeout = determineTimeout(definition);
        if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
            txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
        }

        // 如果是新创建的连接,则绑定到当前线程
        if (txObject.isNewConnectionHolder()) {
            TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
        }
    }
    catch (Throwable ex) {
        if (txObject.isNewConnectionHolder()) {
            DataSourceUtils.releaseConnection(con, obtainDataSource());
            txObject.setConnectionHolder(null, false);
        }
        throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
    }
}

当前不存在事务

分三种情况进行处理,如下:

  1. 事务传播属性设置为PROPAGATION_MANDATORY,表示当前不存在事务就需要抛出异常;
  2. 事务传播属性设置为PROPAGATION_REQUIRED或者PROPAGATION_REQUIRES_NEW或者PROPAGATION_NESTED,表示需要创建新事务;
  3. 事务传播属性设置为PROPAGATION_SUPPORTS或者PROPAGATION_NOT_SUPPORTED或者PROPAGATION_NEVER,表示不需要当前存在事务;
1. 事务传播属性设置为PROPAGATION_MANDATORY

表示当前不存在事务就需要抛出异常,因为此时线程不存在事务,所以直接抛出IllegalTransactionStateException异常,代码如下:

if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
    throw new IllegalTransactionStateException(
            "No existing transaction found for transaction marked with propagation 'mandatory'");
}
2. 事务传播属性设置为PROPAGATION_REQUIRED或者PROPAGATION_REQUIRES_NEW或者PROPAGATION_NESTED

表示需要创建新事务,会先挂起当前事务(空事务),然后创建新事务,代码如下:

else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
        def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
        def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
    // 挂起当前空事务
    SuspendedResourcesHolder suspendedResources = suspend(null);
    if (debugEnabled) {
        logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
    }
    try {
        // 创建新事务
        return startTransaction(def, transaction, debugEnabled, suspendedResources);
    }
    catch (RuntimeException | Error ex) {
        // 出现异常,则恢复原事务状态
        resume(null, suspendedResources);
        throw ex;
    }
}

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);
        }
    }
}

doResume由子类DataSourceTransactionManager实现,代码如下:

protected void doResume(@Nullable Object transaction, Object suspendedResources) {
    // 绑定原连接资源
    TransactionSynchronizationManager.bindResource(obtainDataSource(), suspendedResources);
}
3. 事务传播属性设置为PROPAGATION_SUPPORTS或者PROPAGATION_NOT_SUPPORTED或者PROPAGATION_NEVER

表示不需要当前存在事务,那么直接准备事务状态即可,代码如下:

else {
    if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
        logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                "isolation level will effectively be ignored: " + def);
    }
    boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
    return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}

准备事务信息

TransactionInfo中不仅存在TransactionAttribute,还存在TransactionStatus,代码如下:

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() + "]");
        }
        // 设置事务状态
        txInfo.newTransactionStatus(status);
    }
    else {
        // 事务属性不存在,说明不存在事务
        if (logger.isTraceEnabled()) {
            logger.trace("No need to create transaction for [" + joinpointIdentification +
                    "]: This method is not transactional.");
        }
    }

    // 绑定事务信息到当前线程
    txInfo.bindToThread();
    return txInfo;
}

private void bindToThread() {
    this.oldTransactionInfo = transactionInfoHolder.get();
    transactionInfoHolder.set(this);
}

回滚事务

在事务下执行操作过程中发生异常,则进入异常回滚处理,根据发生的异常类型选择性回滚事务,代码如下:

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);
        }
        // 存在事务且异常类型满足回滚要求
        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 {
            // 事务不存在,或者异常类型不满足回滚要求

            try {
                // 提交事务
                // 如果TransactionStatus.isRollbackOnly()有效,那么也会回滚事务
                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;
            }
        }
    }
}

回滚条件

在介绍获取事务属性时,提到事务属性默认是由SpringTransactionAnnotationParser完成解析的,解析结果为RuleBasedTransactionAttribute,其rollback方法实现如下:

public boolean rollbackOn(Throwable ex) {
    RollbackRuleAttribute winner = null;
    int deepest = Integer.MAX_VALUE;

    // 找到匹配的异常中最上层的异常
    if (this.rollbackRules != null) {
        for (RollbackRuleAttribute rule : this.rollbackRules) {
            int depth = rule.getDepth(ex);
            if (depth >= 0 && depth < deepest) {
                deepest = depth;
                winner = rule;
            }
        }
    }

    // 如果未匹配到异常,则调用父类DefaultTransactionAttribute的实现
    if (winner == null) {
        return super.rollbackOn(ex);
    }

    return !(winner instanceof NoRollbackRuleAttribute);
}

父类DefaultTransactionAttributerollbackOn实现如下:

public boolean rollbackOn(Throwable ex) {
    // 如果是RuntimeException或者是Error
    // 其它异常Spring认为需要由用户拦截处理
    return (ex instanceof RuntimeException || ex instanceof Error);
}

回滚处理

满足回滚条件后,就会由事务管理器进行事务回滚,AbstractPlatformTransactionManager实现了回滚逻辑,代码如下:

public final void rollback(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {
        // 如果事务已结束,则抛出IllegalTransactionStateException异常
        throw new IllegalTransactionStateException(
                "Transaction is already completed - do not call commit or rollback more than once per transaction");
    }

    DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
    // 回滚事务,false表示此次回滚是预期中的
    processRollback(defStatus, false);
}

private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
    try {
        boolean unexpectedRollback = unexpected;

        try {
            // 完成前触发
            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 {
                // 基于外部事务进行的,不是独立的事务,那么只能标记rollbackOnly标识,等到外部事务提交时再做回滚

                // 当前是否存在外部事务
                if (status.hasTransaction()) {
                    if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
                        // 设置rollbackOnly标识
                        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");
                }
                // 如果全局rollbackOnly有效时不提前失败,那么重置意外回滚标识
                if (!isFailEarlyOnGlobalRollbackOnly()) {
                    unexpectedRollback = false;
                }
            }
        }
        catch (RuntimeException | Error ex) {
            // 发生异常,则完成后触发
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            throw ex;
        }

        // 完成后触发
        triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);

        // 设置全局rollbackOnly标识,发生了意外回滚,则抛出UnexpectedRollbackException异常
        if (unexpectedRollback) {
            throw new UnexpectedRollbackException(
                    "Transaction rolled back because it has been marked as rollback-only");
        }
    }
    finally {
        // 完成后清除事务状态并恢复之前挂起的事务
        cleanupAfterCompletion(status);
    }
}

回滚处理分三种情况:

  1. 存在还原点,那么直接回滚到还原点;
  2. 是新事务,那么直接回滚事务;
  3. 当前存在外部事务,但又不属于以上两种情况,多用于JTA,那么只会标识rollbackOnly标识,等外部事务提交时统一处理;
1. 存在还原点

status.rollbackToHeldSavepoint()AbstractTransactionStatus实现,代码如下:

public void rollbackToHeldSavepoint() throws TransactionException {
    Object savepoint = getSavepoint();
    if (savepoint == null) {
        throw new TransactionUsageException(
                "Cannot roll back to savepoint - no savepoint associated with current transaction");
    }
    // 回滚到还原点
    getSavepointManager().rollbackToSavepoint(savepoint);
    // 释放还原点
    getSavepointManager().releaseSavepoint(savepoint);
    // 清除还原点
    setSavepoint(null);
}

如果使用的是数据库,那么getSavepointManager()JdbcTransactionObjectSupport,其rollbackToSavepoint(savepoint)实现如下:

public void rollbackToSavepoint(Object savepoint) throws TransactionException {
    ConnectionHolder conHolder = getConnectionHolderForSavepoint();
    try {
        // 结束连接实现回滚到还原点
        conHolder.getConnection().rollback((Savepoint) savepoint);
        // 重置rollbackOnly标识
        conHolder.resetRollbackOnly();
    }
    catch (Throwable ex) {
        throw new TransactionSystemException("Could not roll back to JDBC savepoint", ex);
    }
}
2. 是新事务

doRollback由子类DataSourceTransactionManager实现,代码如下:

protected void doRollback(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    // 获取当前事务绑定的连接
    Connection con = txObject.getConnectionHolder().getConnection();
    if (status.isDebug()) {
        logger.debug("Rolling back JDBC transaction on Connection [" + con + "]");
    }
    try {
        // 回滚
        con.rollback();
    }
    catch (SQLException ex) {
        throw translateException("JDBC rollback", ex);
    }
}
3. 其它情况

doSetRollbackOnly由子类DataSourceTransactionManager实现,代码如下:

protected void doSetRollbackOnly(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    if (status.isDebug()) {
        logger.debug("Setting JDBC transaction [" + txObject.getConnectionHolder().getConnection() +
                "] rollback-only");
    }
    // 设置rollbackOnly标识
    txObject.setRollbackOnly();
}

回滚后处理

不论事务回滚执行是否成功后,都需要做收尾工作,代码如下:

private void cleanupAfterCompletion(DefaultTransactionStatus status) {
    // 设置事务完成标识
    status.setCompleted();
    if (status.isNewSynchronization()) {
        // 清除同步信息
        TransactionSynchronizationManager.clear();
    }
    if (status.isNewTransaction()) {
        // 清除事务信息
        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());
    }
}

doCleanupAfterCompletion由子类DataSourceTransactionManager实现,代码如下:

protected void doCleanupAfterCompletion(Object transaction) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;

    if (txObject.isNewConnectionHolder()) {
        // 解绑数据库连接资源
        TransactionSynchronizationManager.unbindResource(obtainDataSource());
    }

    Connection con = txObject.getConnectionHolder().getConnection();
    try {
        if (txObject.isMustRestoreAutoCommit()) {
            // 恢复自动提交
            con.setAutoCommit(true);
        }
        // 重置数据库连接
        DataSourceUtils.resetConnectionAfterTransaction(
                con, txObject.getPreviousIsolationLevel(), txObject.isReadOnly());
    }
    catch (Throwable ex) {
        logger.debug("Could not reset JDBC Connection after transaction", ex);
    }

    if (txObject.isNewConnectionHolder()) {
        if (logger.isDebugEnabled()) {
            logger.debug("Releasing JDBC Connection [" + con + "] after transaction");
        }
        // 释放数据库连接如果需要的话
        DataSourceUtils.releaseConnection(con, this.dataSource);
    }

    // 清除持有连接资源信息
    txObject.getConnectionHolder().clear();
}

提交事务

在事务下执行的操作正常结束了,则可以提交事务,代码如下:

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());
    }
}

事务回滚中,提到回滚处理会分三种情况,具体如下:

  1. 存在还原点;
  2. 是新事务;
  3. 当前存在外部事务,但又不属于以上两种情况,多用于JTA;

第三种情况下,只会标识rollbackOnly标识,等外部事务提交时统一处理,所以在事务提交处理中,需要判断事务是否被设置了rollbackOnly标识;
AbstractPlatformTransactionManager实现了事务提交逻辑,代码如下:

public final void commit(TransactionStatus status) throws TransactionException {
    if (status.isCompleted()) {
        // 如果事务已结束,则抛出IllegalTransactionStateException异常
        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()) {
        // 当前事务rollbackOnly标识有效,则进行回滚事务
        if (defStatus.isDebug()) {
            logger.debug("Transactional code has requested rollback");
        }
        // 回滚事务,false表示此次回滚是预期中的
        processRollback(defStatus, false);
        return;
    }

    if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
        // 如果全局rollbackOnly标识有效,且设置这种情况不进行事务提交
        if (defStatus.isDebug()) {
            logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
        }
        // 那就回滚事务,true表示此次回滚是预期外的
        processRollback(defStatus, true);
        return;
    }

    // 提交事务
    processCommit(defStatus);
}

当事务执行一切正常,没有被设置rollbackOnly标识,那么就进入事务提交处理,代码如下:

private void processCommit(DefaultTransactionStatus status) throws TransactionException {
    try {
        boolean beforeCompletionInvoked = false;

        try {
            boolean unexpectedRollback = false;
            // 提交前准备
            prepareForCommit(status);
            // 提交前触发
            triggerBeforeCommit(status);
            // 完成前触发
            triggerBeforeCompletion(status);
            beforeCompletionInvoked = true;

            if (status.hasSavepoint()) {
                // 存在还原点
                if (status.isDebug()) {
                    logger.debug("Releasing transaction savepoint");
                }
                unexpectedRollback = status.isGlobalRollbackOnly();
                // 释放还原点
                status.releaseHeldSavepoint();
            }
            else if (status.isNewTransaction()) {
                // 新事务
                if (status.isDebug()) {
                    logger.debug("Initiating transaction commit");
                }
                unexpectedRollback = status.isGlobalRollbackOnly();
                // 提交事务
                doCommit(status);
            }
            else if (isFailEarlyOnGlobalRollbackOnly()) {
                unexpectedRollback = status.isGlobalRollbackOnly();
            }

            // 设置全局rollbackOnly标识,发生了意外回滚,则抛出UnexpectedRollbackException异常
            if (unexpectedRollback) {
                throw new UnexpectedRollbackException(
                        "Transaction silently rolled back because it has been marked as rollback-only");
            }
        }
        catch (UnexpectedRollbackException ex) {
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
            throw ex;
        }
        catch (TransactionException ex) {
            if (isRollbackOnCommitFailure()) {
                doRollbackOnCommitException(status, ex);
            }
            else {
                triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
            }
            throw ex;
        }
        catch (RuntimeException | Error ex) {
            // 提交过程中发生RuntimeException或者Error,则回滚事务
            if (!beforeCompletionInvoked) {
                triggerBeforeCompletion(status);
            }
            // 提交时异常,回滚事务
            doRollbackOnCommitException(status, ex);
            throw ex;
        }

        try {
            // 提交后触发
            triggerAfterCommit(status);
        }
        finally {
            // 完成后触发
            triggerAfterCompletion(status, TransactionSynchronization.STATUS_COMMITTED);
        }

    }
    finally {
        // 完成后清除事务状态
        cleanupAfterCompletion(status);
    }
}

提交处理分俩种情况:

  1. 存在还原点,那么直接释放还原点;
  2. 是新事务,那么直接提交事务;

1. 存在还原点

status.releaseHeldSavepoint()AbstractTransactionStatus实现,代码如下:

public void releaseHeldSavepoint() throws TransactionException {
    Object savepoint = getSavepoint();
    if (savepoint == null) {
        throw new TransactionUsageException(
                "Cannot release savepoint - no savepoint associated with current transaction");
    }
    // 释放还原点
    getSavepointManager().releaseSavepoint(savepoint);
    // 清除还原点
    setSavepoint(null);
}

2. 是新事务

doCommit由子类DataSourceTransactionManager实现,代码如下:

protected void doCommit(DefaultTransactionStatus status) {
    DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
    Connection con = txObject.getConnectionHolder().getConnection();
    if (status.isDebug()) {
        logger.debug("Committing JDBC transaction on Connection [" + con + "]");
    }
    try {
        // 借助数据库连接完成提交
        con.commit();
    }
    catch (SQLException ex) {
        throw translateException("JDBC commit", ex);
    }
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值