Spring framework版本 5.3.x
1. 核心对象的关系
注解 @EnableTransactionManagement
负责开启事务管理,然后通过 TransactionManagementConfigurationSelector
注入下面两个类:
AutoProxyRegistrar
负责创建代理类
ProxyTransactionManagementConfiguration
负责创建事务管理的逻辑(Spring AOP)
BeanFactoryTransactionAttributeSourceAdvisor
Spring AOP中的Advisor
TransactionAttributeSource
Spring AOP中的Pointcut
TransactionInterceptor
Spring AOP中的advice
这样就能看得出来事务管理其实就是Spring AOP的一个应用实现。
2. 注解事务运行流程
Spring注解事务管理运行流程图:
3. 源码解析
源码从事务管理AOP的三个组件来分析,下面就会分别是:
[TransactionAttributeSource (Poincut)](#3.1 TransactionAttributeSource 源码解析)
[TransactionInterceptor(Advice)](#3.2 TransactionInterceptor源码解析)
BeanFactoryTransactionAttributeSourceAdvisor(Advisor)
3.1 TransactionAttributeSource 源码解析
publicclassAnnotationTransactionAttributeSourceextendsAbstractFallbackTransactionAttributeSourceimplementsSerializable{privatefinalbooleanpublicMethodsOnly;//省略代码publicAnnotationTransactionAttributeSource(){this(true);}publicAnnotationTransactionAttributeSource(booleanpublicMethodsOnly){this.publicMethodsOnly=publicMethodsOnly;if(jta12Present||ejb3Present){this.annotationParsers=newLinkedHashSet<>(4);this.annotationParsers.add(newSpringTransactionAnnotationParser());if(jta12Present){this.annotationParsers.add(newJtaTransactionAnnotationParser());}if(ejb3Present){this.annotationParsers.add(newEjb3TransactionAnnotationParser());}}else{this.annotationParsers=Collections.singleton(newSpringTransactionAnnotationParser());}}}
查看 ProxyTransactionManagementConfiguration
创建 AnnotationTransactionAttributeSource
是使用的无参构造函数。
Tips: 这里调用的是AnnotationTransactionAttributeSource(boolean publicMethodsOnly) 构造函数。这里也就是事务管理只能处理public方法
里面最重要的类就是 SpringTransactionAnnotationParser
注释解析类,其他两个是为了支持java的其他规范。主要的作用就是用来判断当前执行的方法或者类是否包含 @javax.transaction.Transactional,@javax.ejb.TransactionAttribute, @org.springframework.transaction.annotation.Transactional
注解。
看到这里就会有人问了不是说好的 TransactionAttributeSource
相当于 Pointcut
也没用看到实现了 Pointcut
接口。别急下面来看一下 ProxyTransactionManagementConfiguration
类中有这样的一段代码:
@Bean(name=TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicBeanFactoryTransactionAttributeSourceAdvisortransactionAdvisor(TransactionAttributeSourcetransactionAttributeSource,TransactionInterceptortransactionInterceptor){BeanFactoryTransactionAttributeSourceAdvisoradvisor=newBeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource);advisor.setAdvice(transactionInterceptor);if(this.enableTx!=null){advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}returnadvisor;}
将 TransactionAttributeSource
的实现类设置为 BeanFactoryTransactionAttributeSourceAdvisor
的一个属性。(这里其实就是AnnotationTransactionAttributeSource的实例)。下面看一下 BeanFactoryTransactionAttributeSourceAdvisor
类里面有这样的一段代码:
privatefinalTransactionAttributeSourcePointcutpointcut=newTransactionAttributeSourcePointcut(){@Override@NullableprotectedTransactionAttributeSourcegetTransactionAttributeSource(){returntransactionAttributeSource;}};
这不就变成了 Pointcut
了。不是直接继承了接口 Pointcut
而是通过上面代码的方式间接的变成Poincut。看一下TransactionAttributeSourcePointcut
代码
abstractclassTransactionAttributeSourcePointcutextendsStaticMethodMatcherPointcutimplementsSerializable{//省略代码}
通过包装了 AnnotationTransactionAttributeSource
变成 Pointcut
3.2 TransactionInterceptor源码解析
publicclassTransactionInterceptorextendsTransactionAspectSupportimplementsMethodInterceptor,Serializable{//省略代码}
从上面可以看到实现了接口 MethodInterceptor
,那么主要的逻辑就在 MethodInterceptor#invoke
方法中。 TransactionInterceptor实现了 invoke 接口:
@Override@NullablepublicObjectinvoke(MethodInvocationinvocation)throwsThrowable{//获取到目标类Class<?>targetClass=(invocation.getThis()!=null?AopUtils.getTargetClass(invocation.getThis()):null);//AdapttoTransactionAspectSupport'sinvokeWithinTransaction...returninvokeWithinTransaction(invocation.getMethod(),targetClass,newCoroutinesInvocationCallback(){@Override@NullablepublicObjectproceedWithInvocation()throwsThrowable{returninvocation.proceed();}@OverridepublicObjectgetTarget(){returninvocation.getThis();}@OverridepublicObject[]getArguments(){returninvocation.getArguments();}});}
找到调用的目标类,然后调用 TransactionAspectSupport
类的 invokeWithinTransaction
方法。 这个方法也是主要的处理逻辑:
根据 TransactionAttributeSource
来决定使用 ReactiveTransactionManager
还是 PlatformTransactionManager
(这里只分析PlatformTransactionManager)。
TransactionInfotxInfo=createTransactionIfNecessary(ptm,txAttr,joinpointIdentification);
根据 PlatformTransactionManager,TransactionAttributeSource和切入点方法去处理事务管理如何创建,下面看一下 TransactionAspectSupport#createTransactionIfNecessary方法,里面有一段代码:
protectedTransactionInfocreateTransactionIfNecessary(@NullablePlatformTransactionManagertm,@NullableTransactionAttributetxAttr,finalStringjoinpointIdentification){//省略部分代码TransactionStatusstatus=null;if(txAttr!=null){if(tm!=null){//这段代码status=tm.getTransaction(txAttr);}else{}}returnprepareTransactionInfo(tm,txAttr,joinpointIdentification,status);}
事务管理器根据 TransactionAttributeSource
获取事务状态 TransactionStatus
。
status = tm.getTransaction(txAttr)
这段代码里面说明了根据注解 @Transactional
当中的属性如何创建事务,最好包装成 TransactionStatus
。下面来分析这一段代码,由 AbstractPlatformTransactionManager
实现了方法 getTransaction
。
@OverridepublicfinalTransactionStatusgetTransaction(@NullableTransactionDefinitiondefinition)throwsTransactionException{//没有事务定义给出就使用默认的TransactionDefinitiondef=(definition!=null?definition:TransactionDefinition.withDefaults());//获取事务Objecttransaction=doGetTransaction();booleandebugEnabled=logger.isDebugEnabled();//判断事务是否存在if(isExistingTransaction(transaction)){//Existingtransactionfound->checkpropagationbehaviortofindouthowtobehave.returnhandleExistingTransaction(def,transaction,debugEnabled);}//检查新的事务配置if(def.getTimeout()<TransactionDefinition.TIMEOUT_DEFAULT){thrownewInvalidTimeoutException("Invalidtransactiontimeout",def.getTimeout());}//Noexistingtransactionfound->checkpropagationbehaviortofindouthowtoproceed.if(def.getPropagationBehavior()==TransactionDefinition.PROPAGATION_MANDATORY){thrownewIllegalTransactionStateException("Noexistingtransactionfoundfortransactionmarkedwithpropagation'mandatory'");}elseif(def.getPropagationBehavior()==TransactionDefinition.PROPAGATION_REQUIRED||def.getPropagationBehavior()==TransactionDefinition.PROPAGATION_REQUIRES_NEW||def.getPropagationBehavior()==TransactionDefinition.PROPAGATION_NESTED){SuspendedResourcesHoldersuspendedResources=suspend(null);if(debugEnabled){logger.debug("Creatingnewtransactionwithname["+def.getName()+"]:"+def);}try{returnstartTransaction(def,transaction,debugEnabled,suspendedResources);}catch(RuntimeException|Errorex){resume(null,suspendedResources);throwex;}}else{//Create"empty"transaction:noactualtransaction,butpotentiallysynchronization.if(def.getIsolationLevel()!=TransactionDefinition.ISOLATION_DEFAULT&&logger.isWarnEnabled()){logger.warn("Customisolationlevelspecifiedbutnoactualtransactioninitiated;"+"isolationlevelwilleffectivelybeignored:"+def);}booleannewSynchronization=(getTransactionSynchronization()==SYNCHRONIZATION_ALWAYS);returnprepareTransactionStatus(def,null,true,newSynchronization,debugEnabled,null);}}
上面就是根据设置的事务的传播行为来对事务作出处理。事务的传播行为如下:
@Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED) :以非事务方式执行,如果存在当前事务,则挂起当前事务
@Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER) :以非事务方式执行,如果存在事务则抛出异常。
@Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
@Transactional(propagation=Propagation.NESTED) : 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行PROPAGATION_REQUIRED类似的操作。
创建完成 TransactionInfo
后就开始执行业务逻辑方法,如果执行业务逻辑报错那么就执行:
completeTransactionAfterThrowing(txInfo,ex);
然后在 finally 代码块中执行:
@Bean(name=TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)@Role(BeanDefinition.ROLE_INFRASTRUCTURE)publicBeanFactoryTransactionAttributeSourceAdvisortransactionAdvisor(TransactionAttributeSourcetransactionAttributeSource,TransactionInterceptortransactionInterceptor){BeanFactoryTransactionAttributeSourceAdvisoradvisor=newBeanFactoryTransactionAttributeSourceAdvisor();advisor.setTransactionAttributeSource(transactionAttributeSource);advisor.setAdvice(transactionInterceptor);if(this.enableTx!=null){advisor.setOrder(this.enableTx.<Integer>getNumber("order"));}returnadvisor;}0
清除事务的信息,提交事务。到这里整个事务就基本上完成了。
3.3 BeanFactoryTransactionAttributeSourceAdvisor源码解析
publicclassBeanFactoryTransactionAttributeSourceAdvisorextendsAbstractBeanFactoryPointcutAdvisor{@NullableprivateTransactionAttributeSourcetransactionAttributeSource;privatefinalTransactionAttributeSourcePointcutpointcut=newTransactionAttributeSourcePointcut(){@Override@NullableprotectedTransactionAttributeSourcegetTransactionAttributeSource(){returntransactionAttributeSource;}};/***Setthetransactionattributesourcewhichisusedtofindtransaction*attributes.Thisshouldusuallybeidenticaltothesourcereference*setonthetransactioninterceptoritself.*@seeTransactionInterceptor#setTransactionAttributeSource*/publicvoidsetTransactionAttributeSource(TransactionAttributeSourcetransactionAttributeSource){this.transactionAttributeSource=transactionAttributeSource;}/***Setthe{@linkClassFilter}touseforthispointcut.*Defaultis{@linkClassFilter#TRUE}.*/publicvoidsetClassFilter(ClassFilterclassFilter){this.pointcut.setClassFilter(classFilter);}@OverridepublicPointcutgetPointcut(){returnthis.pointcut;}}
这个类比较简单就是将Advice和Pointcut组装成Advisor
4. 总结
Spring事务管理底层使用的是AOP的原理来实现,结合数据库的事务来的。