从servlet到springboot(13) 利用aop实现的事务控制

56 篇文章 2 订阅

上一篇文章我们分析了spring实现aop的原理,在spring中有一个非常重要的功能,就是事务控制,而事务控制就是基于aop来实现的,这一篇我们将分析spring是如何利用aop来实现事务控制的。

 

我们还是在springboot框架下分析,入口是

@EnableTransactionManagement这个注解

点击进入之后

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({TransactionManagementConfigurationSelector.class})
public @interface EnableTransactionManagement {
    boolean proxyTargetClass() default false;

    AdviceMode mode() default AdviceMode.PROXY;

    int order() default 2147483647;
}

这里可以看到import了一个TransactionManagementConfigurationSelector,直接找到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[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};
    default:
        return null;
    }
}

我们在@EnableTransactionManagement终不改定义了adviceMode为PROXY

所以就会给spring中导入AutoProxyRegistrar和ProxyTransactionManagementConfiguration两个组件

 

我们分别分析两个组件

先看这个AutoProxyRegistrar#registerBeanDefinitions
找到关键句分析
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);这句话会注册一个AutoProxyCreator

这个AutoProxyCreator是什么类型的呢,我们继续点击去可以看到是这种类型的

InfrastructureAdvisorAutoProxyCreator

这个类其实作用就是利用后置处理,产生一个增强的代理对象,和aop有点类似

再看另外一个组件ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    public ProxyTransactionManagementConfiguration() {
    }

    @Bean(
        name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
    )
    @Role(2)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        advisor.setTransactionAttributeSource(this.transactionAttributeSource());
        advisor.setAdvice(this.transactionInterceptor());
        advisor.setOrder((Integer)this.enableTx.getNumber("order"));
        return advisor;
    }

    @Bean
    @Role(2)
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }

    @Bean
    @Role(2)
    public TransactionInterceptor transactionInterceptor() {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }

        return interceptor;
    }
}

先看注解,首先这是一个configuration。这个配置类会给给容器中添加各种bean

先看BeanFactoryTransactionAttributeSourceAdvisor

这是一个事务增强器,

advisor.setTransactionAttributeSource(this.transactionAttributeSource());这里会调用
return new AnnotationTransactionAttributeSource();。我们点击进入AnnotationTransactionAttributeSource
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
    this.publicMethodsOnly = publicMethodsOnly;
    this.annotationParsers = new LinkedHashSet(2);
    this.annotationParsers.add(new SpringTransactionAnnotationParser());
    if (jta12Present) {
        this.annotationParsers.add(new JtaTransactionAnnotationParser());
    }

    if (ejb3Present) {
        this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
    }

}

找到SpringTransactionAnnotationParser,

protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
    RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
    Propagation propagation = (Propagation)attributes.getEnum("propagation");
    rbta.setPropagationBehavior(propagation.value());
    Isolation isolation = (Isolation)attributes.getEnum("isolation");
    rbta.setIsolationLevel(isolation.value());
    rbta.setTimeout(attributes.getNumber("timeout").intValue());
    rbta.setReadOnly(attributes.getBoolean("readOnly"));
    rbta.setQualifier(attributes.getString("value"));
    ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList();
    Class<?>[] rbf = attributes.getClassArray("rollbackFor");
    Class[] var7 = rbf;
    int var8 = rbf.length;

这段代码片中可以看到很多熟悉的影子

回到ProxyTransactionManagementConfiguration

advisor.setAdvice(this.transactionInterceptor());这里还会增加一个事务拦截器

 

@Bean
@Role(2)
public TransactionInterceptor transactionInterceptor() {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(this.transactionAttributeSource());
    if (this.txManager != null) {
        interceptor.setTransactionManager(this.txManager);
    }

    return interceptor;
}

这个interceptor类型是TransactionInterceptor

这个类继承了 MethodInterceptor

找到这个类的invoke方法

public Object invoke(final MethodInvocation invocation) throws Throwable {
    Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
    return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
        public Object proceedWithInvocation() throws Throwable {
            return invocation.proceed();
        }
    });
}

这里有一句关键性语句

return this.invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() 

这个执行原理和aop非常类似,就是在执行目标方法的时候会执行拦截器链。,而这个连接器链就是事务拦截器

我们点击进入

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
    final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    final PlatformTransactionManager tm = this.determineTransactionManager(txAttr);
    final String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
    if (txAttr != null && tm instanceof CallbackPreferringPlatformTransactionManager) {
        try {
            Object result = ((CallbackPreferringPlatformTransactionManager)tm).execute(txAttr, new TransactionCallback<Object>() {
                public Object doInTransaction(TransactionStatus status) {
                    TransactionAspectSupport.TransactionInfo txInfo = TransactionAspectSupport.this.prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);

                    TransactionAspectSupport.ThrowableHolder var4;
                    try {
                        Object var3 = invocation.proceedWithInvocation();
                        return var3;
                    } catch (Throwable var8) {
                        if (txAttr.rollbackOn(var8)) {
                            if (var8 instanceof RuntimeException) {
                                throw (RuntimeException)var8;
                            }

                            throw new TransactionAspectSupport.ThrowableHolderException(var8);
                        }

                        var4 = new TransactionAspectSupport.ThrowableHolder(var8);
                    } finally {
                        TransactionAspectSupport.this.cleanupTransactionInfo(txInfo);
                    }

                    return var4;
                }
            });
            if (result instanceof TransactionAspectSupport.ThrowableHolder) {
                throw ((TransactionAspectSupport.ThrowableHolder)result).getThrowable();
            } else {
                return result;
            }
final TransactionAttribute txAttr = this.getTransactionAttributeSource().getTransactionAttribute(method, targetClass);这句话获取到事务属性
final PlatformTransactionManager tm = this.determineTransactionManager(txAttr);这句话获取到事务管理器

我们看下是怎么获取到事务管理器的

protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
    if (txAttr != null && this.beanFactory != null) {
        String qualifier = txAttr.getQualifier();
        if (StringUtils.hasText(qualifier)) {
            return this.determineQualifiedTransactionManager(qualifier);
        } else if (StringUtils.hasText(this.transactionManagerBeanName)) {
            return this.determineQualifiedTransactionManager(this.transactionManagerBeanName);
        } else {
            PlatformTransactionManager defaultTransactionManager = this.getTransactionManager();
            if (defaultTransactionManager == null) {
                defaultTransactionManager = (PlatformTransactionManager)this.transactionManagerCache.get(DEFAULT_TRANSACTION_MANAGER_KEY);
                if (defaultTransactionManager == null) {
                    defaultTransactionManager = (PlatformTransactionManager)this.beanFactory.getBean(PlatformTransactionManager.class);
                    this.transactionManagerCache.putIfAbsent(DEFAULT_TRANSACTION_MANAGER_KEY, defaultTransactionManager);
                }
            }

            return defaultTransactionManager;
        }
    } else {
        return this.getTransactionManager();
    }
}

首先看 if (StringUtils.hasText(qualifier))

@Transactional有没有指定事务管理器,如果没有就设置一个默认的

回到invokeWithinTransaction

Object var3 = invocation.proceedWithInvocation();这个方法就是类似我们上一篇分析的invoke递归调用

我们接着看catch语句中的

有一个this.completeTransactionAfterThrowing(txInfo, var15);

点击进去

protected void completeTransactionAfterThrowing(TransactionAspectSupport.TransactionInfo txInfo, Throwable ex) {
    if (txInfo != null && txInfo.hasTransaction()) {
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "] after exception: " + ex);
        }

        if (txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            } catch (TransactionSystemException var7) {
                this.logger.error("Application exception overridden by rollback exception", ex);
                var7.initApplicationException(ex);
                throw var7;
            } catch (RuntimeException var8) {
                this.logger.error("Application exception overridden by rollback exception", ex);
                throw var8;
            } catch (Error var9) {
                this.logger.error("Application exception overridden by rollback error", ex);
                throw var9;
            }
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());看到有一个rollback

我们归纳下,如果正常就是执行目标方法, 如果异常就执行回滚操作,真正执行回滚操作的是事务控制器做的,spring在这边只做了拦截的动作

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值