Spring Boot源码简析 @EnableTransactionManagement

相关阅读

TransactionAutoConfiguration

Spring框架提供@Transactional注解来支持注解驱动的事务管理;
Spring Boot框架默认开启注解驱动的事务管理,即通过TransactionAutoConfiguration实现事务管理自动配置,代码如下:

@Configuration
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
        DataSourceTransactionManagerAutoConfiguration.class,
        Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public TransactionManagerCustomizers platformTransactionManagerCustomizers(
            ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
        return new TransactionManagerCustomizers(customizers.getIfAvailable());
    }

    @Configuration
    @ConditionalOnSingleCandidate(PlatformTransactionManager.class)
    public static class TransactionTemplateConfiguration {

        private final PlatformTransactionManager transactionManager;

        public TransactionTemplateConfiguration(
                PlatformTransactionManager transactionManager) {
            this.transactionManager = transactionManager;
        }

        @Bean
        @ConditionalOnMissingBean
        public TransactionTemplate transactionTemplate() {
            return new TransactionTemplate(this.transactionManager);
        }

    }

    @Configuration
    @ConditionalOnBean(PlatformTransactionManager.class)
    @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
    public static class EnableTransactionManagementConfiguration {

        @Configuration
        @EnableTransactionManagement(proxyTargetClass = false)
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
        public static class JdkDynamicAutoProxyConfiguration {
        }

        @Configuration
        @EnableTransactionManagement(proxyTargetClass = true)
        // 当spring.aop.proxy-target-class属性值为true或者不存在时生效
        @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
        public static class CglibAutoProxyConfiguration {
        }
    }
}

根据TransactionAutoConfiguration的配置信息可知,当引入PlatformTransactionManager(spring-tx提供)时,该配置类自动生效;
DataSourceTransactionManagerAutoConfiguration会创建TransactionManager,如果当前已存在AbstractTransactionManagementConfiguration,即ProxyTransactionManagementConfiguration,那么意味着已经引入@EnableTransactionManagement注解(ProxyTransactionManagementConfiguration只会被@EnableTransactionManagement注解引入),因此EnableTransactionManagementConfiguration不需要生效;否则就会生效,从而引入@EnableTransactionManagement注解;
EnableTransactionManagementConfiguration生效的情况下,除非指定spring.aop.proxy-target-class配置项为false,此时JdkDynamicAutoProxyConfiguration会生效,否则CglibAutoProxyConfiguration生效,这两配置都会引入@EnableTransactionManagement注解,只是注解的proxyTargetClass属性值不同,该注解会开启事务管理,其实就是引入ProxyTransactionManagementConfiguration

@EnableTransactionManagement

源码

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

    // 代理模式:CGLIB or JDK Interface
    // 默认为false,表示基于JDK Interface
    // 设置为true,会影响所有需要代理的Spring管理的Bean
    boolean proxyTargetClass() default false;

    // 代理应用模式:Proxy or AspectJ
    // Proxy模式只允许通过代理拦截调用,不会拦截同一类中的本地调用
    // AspectJ模式下,proxyTargetClass()无效,会拦截同一类中的本地调用
    AdviceMode mode() default AdviceMode.PROXY;

    // 特定连接点应用多个建议时,事务操作的执行顺序
    int order() default Ordered.LOWEST_PRECEDENCE;

}

简析

通过Import机制,引入TransactionManagementConfigurationSelector

@Import(TransactionManagementConfigurationSelector.class)

TransactionManagementConfigurationSelector继承自AdviceModeImportSelectorAdviceModeImportSelector实现支持AdviceMode算法模板,且支持通用的@EnableXxx注解模式,代码如下:

public final String[] selectImports(AnnotationMetadata importingClassMetadata) {
    // 获取本类支持的注解类型
    // 对于TransactionManagementConfigurationSelector来说为EnableTransactionManagement
    Class<?> annType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class);
    Assert.state(annType != null, "Unresolvable type argument for AdviceModeImportSelector");

    // 获取注解属性数据
    AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
    if (attributes == null) {
        throw new IllegalArgumentException(String.format(
            "@%s is not present on importing class '%s' as expected",
            annType.getSimpleName(), importingClassMetadata.getClassName()));
    }

    // 获取注解的AdviceMode属性值
    AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName());
    // 根据AdviceMode获取引入配置类信息
    // 该方法由子类实现算法细节
    String[] imports = selectImports(adviceMode);
    if (imports == null) {
        throw new IllegalArgumentException(String.format("Unknown AdviceMode: '%s'", adviceMode));
    }
    return imports;
}

@Nullable
protected abstract String[] selectImports(AdviceMode adviceMode);

TransactionManagementConfigurationSelector实现了算法细节selectImports,代码如下:

protected String[] selectImports(AdviceMode adviceMode) {
    switch (adviceMode) {
        case PROXY:
            return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
        case ASPECTJ:
            return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
        default:
            return null;
    }
}

根据@EnableTransactionManagement(proxyTargetClass = true)配置会引入AutoProxyRegistrarProxyTransactionManagementConfiguration

AutoProxyRegistrar

AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,用于向容器里注册自动代理创建器AutoProxyCreator,代码如下:

/**
 * importingClassMetadata : 通过Import引入该类的配置类的元数据信息,本例中配置类为CglibAutoProxyConfiguration
 * registry : Bean定义容器
 */
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    boolean candidateFound = false;
    // 获取配置类的注解列表
    // 本例中注解有:
    //  @Configuration
    //  @EnableTransactionManagement
    //  @ConditionalOnProperty
    Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
    // 遍历注解列表
    for (String annoType : annoTypes) {
        // 获取注解的属性数据
        AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
        if (candidate == null) {
            continue;
        }
        // 获取mode属性值
        Object mode = candidate.get("mode");
        // 获取proxyTargetClass属性值
        Object proxyTargetClass = candidate.get("proxyTargetClass");
        // 过滤出@EnableTransactionManagement注解
        if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
                Boolean.class == proxyTargetClass.getClass()) {
            candidateFound = true;
            // 本例中,mode为AdviceMode.PROXY,proxyTargetClass为true
            if (mode == AdviceMode.PROXY) {
                AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                if ((Boolean) proxyTargetClass) {
                    // 使用subclass-based proxy
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                    return;
                }
            }
        }
    }
    if (!candidateFound && logger.isWarnEnabled()) {
        // 异常LOG记录
        String name = getClass().getSimpleName();
        logger.warn(String.format("%s was imported but no annotations were found " +
                "having both 'mode' and 'proxyTargetClass' attributes of type " +
                "AdviceMode and boolean respectively. This means that auto proxy " +
                "creator registration and configuration may not have occurred as " +
                "intended, and components may not be proxied as expected. Check to " +
                "ensure that %s has been @Import'ed on the same class where these " +
                "annotations are declared; otherwise remove the import of %s " +
                "altogether.", name, name, name));
    }
}

核心逻辑为AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);,代码如下:

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

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

    // 判断当前容器中是否存在自动代理创建器的Bean定义
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        // 获取已存在的Bean定义
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        // 判断已存在的Bean定义的className和当前是否一致
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            // 不一致则使用优先级更高的
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }

    // 根据当前class创建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;
}

public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        // 添加Bean定义的proxyTargetClass属性
        definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
    }
}

ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration是一个配置类,继承自AbstractTransactionManagementConfiguration
AbstractTransactionManagementConfiguration实现了ImportAware接口,会注入@EnableTransactionManagement注解属性数据,同时注入TransactionManagementConfigurer配置,代码如下:

public void setImportMetadata(AnnotationMetadata importMetadata) {
    // 获取@EnableTransactionManagement注解属性数据
    this.enableTx = AnnotationAttributes.fromMap(
            importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
    if (this.enableTx == null) {
        throw new IllegalArgumentException(
                "@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
    }
}

@Autowired(required = false)
void setConfigurers(Collection<TransactionManagementConfigurer> configurers) {
    if (CollectionUtils.isEmpty(configurers)) {
        return;
    }
    // // TransactionManagementConfigurer bean只能存在一个
    if (configurers.size() > 1) {
        throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");
    }
    TransactionManagementConfigurer configurer = configurers.iterator().next();
    // 使用自定义的事务管理器
    this.txManager = configurer.annotationDrivenTransactionManager();
}

@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionalEventListenerFactory transactionalEventListenerFactory() {
    // 注入监听器工厂,支持@TransactionalEventListener注解标注的方法,来监听事务相关的事件
    return new TransactionalEventListenerFactory();
}

ProxyTransactionManagementConfiguration会向容器中注入BeanFactoryTransactionAttributeSourceAdvisorTransactionAttributeSourceTransactionInterceptor,代码如下:

@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
    // 事务管理核心Advisor
    BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    advisor.setTransactionAttributeSource(transactionAttributeSource());
    // 设置增强
    advisor.setAdvice(transactionInterceptor());
    if (this.enableTx != null) {
        advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    }
    return advisor;
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
    // 基于注解的事务属性源
    return new AnnotationTransactionAttributeSource();
}

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
    // 事务拦截器
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource());
    if (this.txManager != null) {
        // 设置事务管理器
        interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
}
AnnotationTransactionAttributeSource

AnnotationTransactionAttributeSource是基于注解的事务属性源,内部维护TransactionAnnotationParser集合,用于解析类或方法的事务属性,代码如下:

public AnnotationTransactionAttributeSource() {
    // 默认只能解析public方法
    this(true);
}

public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
    this.publicMethodsOnly = publicMethodsOnly;
    this.annotationParsers = new LinkedHashSet<>(2);
    // 默认持有SpringTransactionAnnotationParser支持Spring事务注解
    this.annotationParsers.add(new SpringTransactionAnnotationParser());
    if (jta12Present) {
        // 持有JtaTransactionAnnotationParser支持JTS事务注解
        this.annotationParsers.add(new JtaTransactionAnnotationParser());
    }
    if (ejb3Present) {
        // 持有Ejb3TransactionAnnotationParser支持EJB3事务注解
        this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
    }
}

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

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

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
    // 遍历内部的事务注解解析器
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        // 解析事务属性
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
        if (attr != null) {
            // 解析成功直接返回
            return attr;
        }
    }
    return null;
}
SpringTransactionAnnotationParser

SpringTransactionAnnotationParser实现了TransactionAnnotationParser接口,负责解析@Transactional注解,核心代码如下:

public boolean isCandidateClass(Class<?> targetClass) {
    // 指定类是否可能标注@Transactional注解
    return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    // 寻找该元素(方法或者类)上是否标注@Transactional注解
    AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
            element, Transactional.class, false, false);
    if (attributes != null) {
        // 存在,则继续解析@Transactional注解属性
        return parseTransactionAnnotation(attributes);
    }
    else {
        return null;
    }
}

public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
    return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
}

/**
 * 进一步解析@Transactional注解属性
 */
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;
}
TransactionInterceptor

TransactionInterceptor继承自TransactionAspectSupport,并实现了MethodInterceptor,代码如下:

public Object invoke(MethodInvocation invocation) throws Throwable {
    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,代码如下:

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);
    // 获取方法ID字符串
    final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

    if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
        // 标准的事务管理:getTransaction/commit/rollback calls.

        // 创建事务信息,根据事务属性决定是否创建事务
        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;
    }
}

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 {
                // 提交事务
                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;
            }
        }
    }
}

protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
    if (txAttr == null || this.beanFactory == null) {
        // 直接返回全局事务管理器
        return getTransactionManager();
    }

    // 获取事务属性指定的事务管理器名称
    String qualifier = txAttr.getQualifier();
    if (StringUtils.hasText(qualifier)) {
        // 若指定事务管理器名称,则根据名称查找对应的Bean
        return determineQualifiedTransactionManager(this.beanFactory, qualifier);
    }
    else if (StringUtils.hasText(this.transactionManagerBeanName)) {
        // 指定了全局事务管理器名称,则根据名称查找对应的Bean
        return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
    }
    else {
        // 获取全局事务管理器
        PlatformTransactionManager defaultTransactionManager = getTransactionManager();
        if (defaultTransactionManager == null) {
            // 从本地缓存中获取默认事务管理器
            defaultTransactionManager = this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
            if (defaultTransactionManager == null) {
                // 从容器中获取PlatformTransactionManager
                defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class);
                // 缓存该事务管理器
                this.transactionManagerCache.putIfAbsent(
                        DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
            }
        }
        return defaultTransactionManager;
    }
}

private PlatformTransactionManager determineQualifiedTransactionManager(BeanFactory beanFactory, String qualifier) {
    // 从本地缓存中获取指定名称的事务管理器
    PlatformTransactionManager txManager = this.transactionManagerCache.get(qualifier);
    if (txManager == null) {
        // 本地缓存不存在,则从容器中根据类型和名称查找事务管理器
        txManager = BeanFactoryAnnotationUtils.qualifiedBeanOfType(
                beanFactory, PlatformTransactionManager.class, qualifier);
        // 缓存该事务管理器,方便下次直接从本地缓存中获取
        this.transactionManagerCache.putIfAbsent(qualifier, txManager);
    }
    return txManager;
}
BeanFactoryTransactionAttributeSourceAdvisor

ProxyTransactionManagementConfiguration中,为BeanFactoryTransactionAttributeSourceAdvisor设置了TransactionInterceptor作为增强,设置了AnnotationTransactionAttributeSource作为事务属性源,代码如下:

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		@Nullable
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};

BeanFactoryTransactionAttributeSourceAdvisor内部的PointcutTransactionAttributeSourcePointcut,使用AnnotationTransactionAttributeSource作为事务属性源,实现切入匹配判断,代码如下:

public boolean matches(Method method, @Nullable Class<?> targetClass) {
    // 不支持TransactionalProxy
    if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
        return false;
    }
    // 获取事务属性源
    TransactionAttributeSource tas = getTransactionAttributeSource();
    // 若当前方法存在事务属性则匹配成功
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

TransactionManagementConfigurer

Spring Boot框架默认会提供DataSourceTransactionManagerJpaTransactionManager事务管理器,用户可以通过实现接口TransactionManagementConfigurer来提供自定义PlatformTransactionManager实现;

源码

public interface TransactionManagementConfigurer {
    PlatformTransactionManager annotationDrivenTransactionManager();
}

配置

@Configuration
public class JdbcConfig implements TransactionManagementConfigurer {

    @Override
    public PlatformTransactionManager annotationDrivenTransactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
        return dataSourceTransactionManager;
    }
}

简析

当自定义TransactionManagementConfigurer实现并放入容器后,AbstractTransactionManagementConfiguration.setConfigurers方法会搜索容器内所有的TransactionManagementConfigurer实现(仅支持一个),并将自定义的事务管理器作为全局默认事务管理器。

@Transactional

源码

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {

    // 指定事务管理器名称
    @AliasFor("transactionManager")
    String value() default "";

    // 指定事务管理器名称
    @AliasFor("value")
    String transactionManager() default "";

    // 事务传播行为
    Propagation propagation() default Propagation.REQUIRED;

    // 事务隔离级别
    Isolation isolation() default Isolation.DEFAULT;

    // 事务超时时间
    int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;

    // 是否只读
    boolean readOnly() default false;

    // 回滚异常类型
    Class<? extends Throwable>[] rollbackFor() default {};

    // 回滚异常类名
    String[] rollbackForClassName() default {};

    // 不回滚异常类型
    Class<? extends Throwable>[] noRollbackFor() default {};

    // 不回滚异常类名
    String[] noRollbackForClassName() default {};
}

使用

  1. 标注在类上,表示该类的所有方法都被标注;
  2. 标注在方法上,优先于方法所在类上的注解,若存在的话;

和@EnableAsync区别

  • @EnableTransactionManagement借助自动代理创建器AutoProxyCreator实现代理;
  • @EnableAsync借助Bean后置处理器BeanPostProcessor实现代理;

事务不生效原因

  1. 事务切入的方法默认必须是public方法,见AnnotationTransactionAttributeSource
  2. Spring框架只对RuntimeException进行回滚;
  3. 业务和事务在同一个线程中;
  4. 非事务方法调用同类中的事务方法,则事务不生效;
    1. 事务方法调用同类中的事务/非事务方法,调用方法的事务生效;
    2. 非事务方法通过本类的代理对象调用事务方法,被调用方法的事务生效;
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
@EnableTransactionManagement注解的作用是开启Spring的事务管理功能。在Spring Boot项目中,通常将该注解配置在启动类上,它的效果等同于在一般的Spring项目中配置<tx:annotation-driven />。开启事务支持后,可以在访问数据库的Service方法上添加@Transactional注解,从而使得这些方法支持事务。当@EnableTransactionManagement注解放在类上时,表示该类中的所有方法都支持事务。 @EnableTransactionManagement的作用是为了简化事务的配置,使得开发者可以更方便地使用事务管理功能。通过该注解,开发者无需手动配置事务管理器、事务通知器等,Spring会自动为其创建相应的Bean,并将其应用到需要事务管理的方法上。 @EnableTransactionManagement的使用可以提高代码的可读性和可维护性,同时也能够确保数据的一致性和完整性。通过使用@Transactional注解,可以将多个数据库操作作为一个事务进行管理,当其中任何一个操作失败时,整个事务会被回滚,保证数据的一致性。 范例:<<引用:spring-boot @EnableTransactionManagement 作用。该注解表示开启事务支持 在springboot项目中一般配置在启动类上 效果等同于一般spring中 xml配置的<tx:annotation-driven />。 开启事务支持后,然后在访问数据库的Service方法上添加注解 @Transactional 后当前方法将支持事务。 放在类上时 所有方法支持事务。>> @EnableTransactionManagement注解的作用是开启Spring的事务管理功能。在Spring Boot项目中,通常将该注解配置在启动类上,它的效果等同于在一般的Spring项目中配置<tx:annotation-driven />。开启事务支持后,可以在访问数据库的Service方法上添加@Transactional注解,从而使得这些方法支持事务。当@EnableTransactionManagement注解放在类上时,表示该类中的所有方法都支持事务。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值