32.Spring事务原理之@EnableTransactionManagement


highlight: arduino-light

9.Spring事务原理之@EnableTransactionManagement

Spring提供的AOP功能有两种实现方式,可选值有PROXY 和 ASPECTJ,默认值为AdviceMode.PROXY。

一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。

@EnableTransactionManagement中的mode选项就是设定Spring用哪种方式提供AOP功能。

AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。

需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。

如果想让自调用触发代理,可以考虑使用ASPECTJ。

由于AdviceMode.PROXY应用比较广泛,而AdviceMode.ASPECTJ应用较少。所以我们主要是讲AdviceMode.PROXY。

参考:https://www.cnblogs.com/54chensongxia/p/13177933.html

@EnableTransactionManagement

``` /* @EnableTransactionManagement注解有以下几个属性 proxyTargetClass属性: 指定事务的AOP是通过JDK动态代理实现,还是CGLIB动态代理实现。 true的话是CGLIB,false的话是JDK动态代理需要注意的是这个属性只有在AdviceMode设置成AdviceMode.PROXY的情况下才会生效。 假如使用ASPECTJ的AOP框架的话,这个属性就失效了。 另外,这个属性的设定可能会影响其他需要动态代理的类。 比如说将这个属性设置成true,@Async注解的方法也会使用CGLIB生成代理类。 但是总的来说,这个属性的设置不会造成什么负面影响,毕竟JDK动态代理和CGLIB动态代理都能实现我们的需求 ​ mode属性: Spring提供的AOP功能有两种实现方式,一种是Spring自带的AOP功能,主要靠JDK代理和CGLIB代理实现,另外一种是通过第三方框架ASPECTJ实现。 这个选项就是设定Spring用哪种方式提供AOP功能。AdviceMode.PROXY表示用Spring自带的AOP功能,AdviceMode.ASPECTJ表示使用ASPECTJ提供AOP功能。 需要注意的是Spring自带的AOP功能不支持本地调用的代理功能,也就是说同一个类中的方法互相调用不会“触发”代理方法。如果想让自调用触发代理,可以考虑使用ASPECTJ。 ​ order属性:表示当一个连接点(方法)被切多次时(也就是说有多个Advice和连接点关联),这些连接点的执行顺序。 */ @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement {

//true:cglib  false:jdk
boolean proxyTargetClass() default false;

​ //默认是AdviceMode.PROXY AdviceMode mode() default AdviceMode.PROXY; ​ int order() default Ordered.LOWEST_PRECEDENCE; ​ } ```

public enum AdviceMode { /** * JDK proxy-based advice. */ PROXY, /** * AspectJ weaving-based advice. */ ASPECTJ }

TransactionManagementConfigurationSelector

注意是1个Selector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { @Override protected String[] selectImports(AdviceMode adviceMode) { //这里的AdviceMode 由        //AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来 //就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY; switch (adviceMode) { case PROXY: //如果是 PROXY 那么返回的是                //AutoProxyRegistrar和ProxyTransactionManagementConfiguration return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: //如果是 ASPECTJ 那么返回的是 /** 如果类加载器有"javax.transaction.Transactional" 那么创建AspectJJtaTransactionManagementConfiguration 否则创建AspectJTransactionManagementConfiguration */ return new String[] {determineTransactionAspectClass()}; default: return null; } } //省略代码 } ​

TransactionManagementConfigurationSelector继承自AdviceModeImportSelector

所以这个代码

selector.selectImports(currentSourceClass.getMetadata());

进入的是

AdviceModeImportSelector#selectImports(AnnotationMetadata importingClassMetadata)

``` public abstract class AdviceModeImportSelector implements ImportSelector {

public static final String DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME = "mode";

protected String getAdviceModeAttributeName() {
    return DEFAULT_ADVICE_MODE_ATTRIBUTE_NAME;
}

@Override
public final String[] selectImports(AnnotationMetadata 
                                        importingClassMetadata) {
    Class<?> annType = GenericTypeResolver.resolveTypeArgument
                        (getClass(), AdviceModeImportSelector.class);

     /***
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @EnableTransactionManagement
    @ComponentScan("transaction")
    public class BeanConfig {
    }
    因为TransactionManagementConfigurationSelector
    是被@EnableTransactionManagement导入的
    @EnableTransactionManagement加在了BeanConfig上面
    所以读取的metadata是BeanConfig上面的注解元数据
    元数据:是3个注解的值
     0 =  EnableAspectJAutoProxy
                (proxyTargetClass=false, exposeProxy=false)"
     1 =  EnableTransactionManagement
                (mode=PROXY, order=2147483647, proxyTargetClass=false)"
     2 =  ComponentScan
                (scopeResolver=class org.springframework.context.annotation.AnnotationScopeMetadataResolver, lazyInit=false, resourcePattern=**.class, useDefaultFilters=true, excludeFilters=[], scopedProxy=DEFAULT, basePackageClasses=[], nameGenerator=interface org.springframework.beans.factory.support.BeanNameGenerator, basePackages=[], value=[], includeFilters=[])"
     */
    AnnotationAttributes attributes = 
        AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
    if (attributes == null) {
        throw new IllegalArgumentException();
    }
     //这里的adviceMode 
    //由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来
    //就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY;
    AdviceMode adviceMode = attributes.getEnum(getAdviceModeAttributeName());
    //调用TransactionManagementConfigurationSelector.selectImports导入组件
    String[] imports = selectImports(adviceMode);
    if (imports == null) {
        throw new IllegalArgumentException
                        ("Unknown AdviceMode: " + adviceMode);
    }
    return imports;
}

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

} ```

调用TransactionManagementConfigurationSelector.selectImports

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { @Override protected String[] selectImports(AdviceMode adviceMode) { //这里的AdviceMode //由AdviceModeImportSelector.selectImports(AnnotationMetadata) 传过来 //就是读取@EnableTransactionManagement注解的mode属性 默认是 AdviceMode.PROXY; switch (adviceMode) { case PROXY: //如果是PROXY 那么返回的是 //AutoProxyRegistrar和ProxyTransactionManagementConfiguration return new String[] { AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}; case ASPECTJ: //如果是 ASPECTJ 那么返回的是 /** 如果类加载器有"javax.transaction.Transactional" 那么创建AspectJJtaTransactionManagementConfiguration 否则创建AspectJTransactionManagementConfiguration JtaTransaction和Transaction */ return new String[] {determineTransactionAspectClass()}; default: return null; } }

可以看到,如果是Proxy代理的话,会往spring ioc容器注入两个组件如下

AutoProxyRegistrar.class和ProxyTransactionManagementConfiguration.class

AutoProxyRegistrar

而AutoProxyRegistrar又是个BeanDefinitionRegistrar,所以它又给容器导入了一些组件

这个BeanDefinitionRegistrar也是往容器注入组件的工具,看看它的registerBeanDefinitions方法

又注入了什么组件?

模式1:Proxy

导入:AutoProxyRegistrar

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) { registrars.forEach((registrar, metadata) -> registrar.registerBeanDefinitions(metadata, this.registry)); }

解析mode和proxyTagetClass

注入InfrastructureAdvisorAutoProxyCreator

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar { ​ private final Log logger = LogFactory.getLog(getClass());       //importingClassMetadata是beanConfig上的注解集合 @Override public void registerBeanDefinitions(AnnotationMetadata                                   importingClassMetadata,                                        BeanDefinitionRegistry registry) { boolean candidateFound = false; Set<String> annTypes = importingClassMetadata.getAnnotationTypes(); for (String annType : annTypes) { AnnotationAttributes candidate =               AnnotationConfigUtils.attributesFor               (importingClassMetadata, annType); if (candidate == null) { continue; }            //默认是PROXY Object mode = candidate.get("mode");            //默认是false Object proxyTargetClass = candidate.get("proxyTargetClass"); if (mode != null &&                proxyTargetClass != null &&                AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) { candidateFound = true; if (mode == AdviceMode.PROXY) {                    //注意:                    //切面注册的是AnnotationAwareAspectJAutoProxyCreator //事务会注入InfrastructureAdvisorAutoProxyCreator                    //如果事务和切面同时存在使用AnnotationAwareAspectJAutoProxyCreator                    //主要就是判断是否存在名为internalAutoProxyCreator的bean                    //如果不存在就注入AnnotationAwareAspectJAutoProxyCreator                    //如果存在就判断当前注入的bean权重和已经注入的bean的权重                    //如果当前注入的bean的权重大于已经注入的bean的权重                    //则注入当前bean AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); if ((Boolean) proxyTargetClass) { AopConfigUtils                         .forceAutoProxyCreatorToUseClassProxying(registry); return; } } } } } }

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

@Nullable public static BeanDefinition registerAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { //注意这里写死的是InfrastructureAdvisorAutoProxyCreator return registerOrEscalateApcAsRequired (InfrastructureAdvisorAutoProxyCreator.class, registry, source); }

注册InfrastructureAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator继承SmartInstantiationAwareBeanPostProcessor也就是一个BeanPostProcessor。

继承了AbstractAdvisorAutoProxyCreator,AbstractAdvisorAutoProxyCreator重写了BeanPostProcessor的postProcessAfterInitialization。

postProcessAfterInitialization方法的主要的作用

1.在代理寻找候选Advisor时,会调用

InfrastructureAdvisorAutoProxyCreator#isEligibleAdvisorBean

判断是否是合适的AdvisorBean

主要是判断advisorName的角色是否是ROLE_INFRASTRUCTURE=2

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

其实就是为了让ProxyTransactionManagementConfiguration注册的BeanFactoryTransactionAttributeSourceAdvisor能被加入到候选的Advisor中。

//继续注入InfrastructureAdvisorAutoProxyCreator //注意:切面注册的是AnnotationAwareAspectJAutoProxyCreator //事务会注入InfrastructureAdvisorAutoProxyCreator //如果事务和切面都有 注入得是AnnotationAwareAspectJAutoProxyCreator //区别在于 2个类的isEligibleAdvisorBean方法 //AnnotationAwareAspectJAutoProxyCreator是直接返回true //InfrastructureAdvisorAutoProxyCreator是判断了 this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE

2.生成代理类

public class InfrastructureAdvisorAutoProxyCreator extends   AbstractAdvisorAutoProxyCreator { @Nullable private ConfigurableListableBeanFactory beanFactory; ​ @Override protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) { super.initBeanFactory(beanFactory); this.beanFactory = beanFactory; } ​ /*** * 在做代理时 判断是否是合适的候选Advisor类 * AbstractAdvisorAutoProxyCreator#findCandidateAdvisors */ @Override protected boolean isEligibleAdvisorBean(String beanName) { /**** 这个条件是寻找AVISOR的Role是 ROLE_INFRASTRUCTURE 比如 BeanFactoryTransactionAttributeSourceAdvisor @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME) @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {} */ return (this.beanFactory != null &&                this.beanFactory               .containsBeanDefinition(beanName) &&                //判断getRole() == BeanDefinition.ROLE_INFRASTRUCTURE this.beanFactory               .getBeanDefinition(beanName)               .getRole() == BeanDefinition.ROLE_INFRASTRUCTURE); } ​ } ​

导入:ProxyTransactionManagementConfiguration

``` @Configuration @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public class ProxyTransactionManagementConfiguration extends
  AbstractTransactionManagementConfiguration { ​ /** 使用@Bean注入事务增强器(Advisor) 在事务类创建的时候,被AutoProxyRegistrar导入的组件 InfrastructureAdvisorAutoProxyCreator拦截, InfrastructureAdvisorAutoProxyCreator拦截的逻辑就是增强事务类的事务方法 而BeanFactoryTransactionAttributeSourceAdvisor作为增强器。 需要把类中所有的方法与需要增强的方法(这里是指被@Transactional标记的方法)进行匹配 匹配成功的增强器 最后会转成拦截器(MethodInterceptor,就是下面的TransactionInterceptor) 然后与目标方法一起在拦截器链中被执行,达到方法增强的效果; ​ BeanFactoryTransactionAttributeSourceAdvisor的继承关系如下: --Advisor 顶级接口 --PointcutAdvisor --AbstractPointcutAdvisor --AbstractBeanFactoryPointcutAdvisor --BeanFactoryTransactionAttributeSourceAdvisor

​      AOP中AspectJPointcutAdvisor的继承关系如下,与AbstractPointcutAdvisor一样,都实现了 --Advisor         --PointcutAdvisor           --AspectJPointcutAdvisor */ @Bean(name = TransactionManagementConfigUtils.TRANSACTIONADVISORBEANNAME) @Role(BeanDefinition.ROLEINFRASTRUCTURE) public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {        //主要看它的getPointCut方法        //会创建1个methodMatcher        //根据methodMatcher判断方法是否需要匹配被应用事务 BeanFactoryTransactionAttributeSourceAdvisor advisor           = new BeanFactoryTransactionAttributeSourceAdvisor(); //注入解析器 //判断是否canApply的时候会用上 //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解 advisor.setTransactionAttributeSource(transactionAttributeSource());        //transactionInterceptor()返回1个transactionInterceptor        //有2个用处:        //1.在getInterceptorsAndDynamicInterceptionAdvice方法        //将BeanFactoryTransactionAttributeSourceAdvisor转换为对应的interceptor         //2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器        //具体看transactionInteceptor的invoke方法 advisor.setAdvice(transactionInterceptor()); if (this.enableTx != null) { advisor.setOrder(this.enableTx. getNumber("order")); } return advisor; }    

/***
 使用@Bean注入 AnnotationTransactionAttributeSource
 主要注入2个@Transactional注解解析器
 this.annotationParsers.add(new SpringTransactionAnnotationParser());
 this.annotationParsers.add(new JtaTransactionAnnotationParser());
 */
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
    /***
     true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
     public AnnotationTransactionAttributeSource() {
        this(true);
     }
     */
    return new AnnotationTransactionAttributeSource();

}        /*    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()); } } / /* 被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor 保存了事务属性信息,事务管理器 在目标方法执行的时候;执行拦截器链 */ @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); //执行代理类的invoke方法的时候会用上 //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在 interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) {            //设置事务管理器 interceptor.setTransactionManager(this.txManager); } return interceptor; } ​ } ```

ProxyTransactionManagementConfiguration是一个配置类。

主要有三个方法,每个方法作用如下:

注入BeanFactoryTransactionAttributeSourceAdvisor

向IOC容器中导入事务增强器:BeanFactoryTransactionAttributeSourceAdvisor

在bean被代理做事务增强时。这个advisor会被选为候选advisor用于增强事务。注意是候选

BeanFactoryTransactionAttributeSourceAdvisor相当于是1个中介。

把TransactionAttributeSource和TransactionInterceptor 关联起来。

TransactionAttributeSource主要用于获取解析器解析@Transaction注解

TransactionInterceptor主要用于方法拦截执行拦截器链。

``` public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor { ​ @Nullable private TransactionAttributeSource transactionAttributeSource;     //注意pointcut是 TransactionAttributeSourcePointcut 间接继承了MethodMatcher    //在判断是否是可用的advisor时会用到这个TransactionAttributeSourcePointcut    //主要是调用matches方法    //TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut    //StaticMethodMatcherPointcut extends StaticMethodMatcher implements Pointcut    //StaticMethodMatcher implements MethodMatcher     //会创建1个methodMatcher     //根据methodMatcher判断方法是否需要匹配被应用事务 private final TransactionAttributeSourcePointcut pointcut       = new TransactionAttributeSourcePointcut() { @Override @Nullable protected TransactionAttributeSource getTransactionAttributeSource() { return transactionAttributeSource; } };

public void setTransactionAttributeSource       (TransactionAttributeSource transactionAttributeSource) { this.transactionAttributeSource = transactionAttributeSource; }

public void setClassFilter(ClassFilter classFilter) {
    this.pointcut.setClassFilter(classFilter);
}

​ @Override public Pointcut getPointcut() { return this.pointcut; } } ​ ```

根据methodMatcher判断方法是否需要匹配被应用事务

``` abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { ​ @Override public boolean matches(Method method, Class> targetClass) { if (TransactionalProxy.class.isAssignableFrom(targetClass) || PlatformTransactionManager.class.isAssignableFrom(targetClass) || PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) { return false; }         TransactionAttributeSource tas = getTransactionAttributeSource();

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

@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();

} ```

注入AnnotationTransactionAttributeSource

向IOC容器中导入事务注解@Transactional的解析器AnnotationTransactionAttributeSource

主要是注入了2个@Transactional的解析器,解析@Transactional的属性值。

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

这2个解析器在2个地方会被用到:

1.判断候选advisor(候选的advisor指的是所有的advisor),是否可以被应用需要调用canApply方法判断

2.在使用jdk代理时,调用代理的invoke方法,会使用这2个解析器去解析@Transactional。然后再去匹配是否需要应用BeanFactoryTransactionAttributeSourceAdvisor。

``` /* 使用@Bean注入 AnnotationTransactionAttributeSource 主要注入2个@Transactional注解解析器 this.annotationParsers.add(new SpringTransactionAnnotationParser()); this.annotationParsers.add(new JtaTransactionAnnotationParser()); / @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionAttributeSource transactionAttributeSource() { / true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧? public AnnotationTransactionAttributeSource() { this(true); } */ return new AnnotationTransactionAttributeSource(); } ​

public AnnotationTransactionAttributeSource() {
    this(true);
}

​ ​ ​ public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) { this.publicMethodsOnly = publicMethodsOnly; if (jta12Present || ejb3Present) { this.annotationParsers = new LinkedHashSet<>(4); this.annotationParsers.add(new SpringTransactionAnnotationParser()); if (jta12Present) { this.annotationParsers.add(new JtaTransactionAnnotationParser()); } if (ejb3Present) { this.annotationParsers.add(new Ejb3TransactionAnnotationParser()); } } else { this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser()); } } ```

注入TransactionInterceptor

BeanFactoryTransactionAttributeSourceAdvisor方法中设置了 advisor.setAdvice(transactionInterceptor());

BeanFactoryTransactionAttributeSourceAdvisor被加入拦截器链,底层使用的还是TransactionInterceptor。

TransactionInterceptor中设置了事务管理器TransactionManager

TransactionManager中实现了方法开启事务 提交事务 异常回滚事务等。

       /**         被@Transactional标记的事务方法的拦截器,实际是一个MethodInterceptor         保存了事务属性信息,事务管理器         在目标方法执行的时候;执行拦截器链         */ ​ //transactionInterceptor()返回1个transactionInterceptor        //有2个用处:        //1.获取调用链时调用getInterceptorsAndDynamicInterceptionAdvice方法        //将BeanFactoryTransactionAttributeSourceAdvisor        //转换为transactionInterceptor //因为在BeanFactoryTransactionAttributeSourceAdvisor的注入方法中已经设置了 //advisor.setAdvice(transactionInterceptor());         //2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器        //具体看transactionInteceptor的invoke方法 @Bean @Role(BeanDefinition.ROLE_INFRASTRUCTURE) public TransactionInterceptor transactionInterceptor() { TransactionInterceptor interceptor = new TransactionInterceptor(); //执行代理类的invoke方法的时候会用上 //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解是否存在 interceptor.setTransactionAttributeSource(transactionAttributeSource()); if (this.txManager != null) {            //设置事务管理器 interceptor.setTransactionManager(this.txManager); } return interceptor; }

向IOC容器中导入事务方法拦截器TransactionInterceptor

在使用jdk代理时,调用代理的invoke方法,会取出TransactionInterceptor的TransactionManager做事务增强

@Override @Nullable public Object invoke(MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); ​ // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed); }

@Nullable protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable { ​ // If the transaction attribute is null, the method is non-transactional. TransactionAttributeSource tas = getTransactionAttributeSource(); final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);        //获取设置的事务管理器 final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass, txAttr); ​ if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) { // Standard transaction demarcation with getTransaction and commit/rollback calls. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification); ​ Object retVal; try { // This is an around advice: Invoke the next interceptor in the chain. // This will normally result in a target object being invoked. retVal = invocation.proceedWithInvocation(); } catch (Throwable ex) { // target invocation exception completeTransactionAfterThrowing(txInfo, ex); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } ​ else { Object result; final ThrowableHolder throwableHolder = new ThrowableHolder(); ​ // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. try { result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, status -> { TransactionInfo txInfo = prepareTransactionInfo(tm, txAttr, joinpointIdentification, status); try { return invocation.proceedWithInvocation(); } catch (Throwable ex) { if (txAttr.rollbackOn(ex)) { // A RuntimeException: will lead to a rollback. if (ex instanceof RuntimeException) { throw (RuntimeException) ex; } else { throw new ThrowableHolderException(ex); } } else { // A normal return value: will lead to a commit. throwableHolder.throwable = ex; return null; } } finally { cleanupTransactionInfo(txInfo); } }); } catch (ThrowableHolderException ex) { throw ex.getCause(); } catch (TransactionSystemException ex2) { if (throwableHolder.throwable != null) { logger.error("Application exception overridden by commit exception", throwableHolder.throwable); ex2.initApplicationException(throwableHolder.throwable); } throw ex2; } catch (Throwable ex2) { if (throwableHolder.throwable != null) { logger.error("Application exception overridden by commit exception", throwableHolder.throwable); } throw ex2; } ​ // Check result state: It might indicate a Throwable to rethrow. if (throwableHolder.throwable != null) { throw throwableHolder.throwable; } return result; } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值