上一篇文章我们分析了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在这边只做了拦截的动作