开启事务的注解
@EnableTransactionManagement
此注解有一个由spring导入第三方的类:
TransactionManagementConfigurationSelector
①:AutoProxyRegistrar.class
该类实现了ImportBeanDefinitionRegistrar接口,用于预定义bean的注册,之后调用aop的方法
一个是spring初始化的时候,bean要实现的接口,Ordered,
一个是预定义bean在诸如的时候的名称,注入的流程术语ioc分域。
- The bean name of the internally managed auto-proxy creator.
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
“org.springframework.aop.config.internalAutoProxyCreator”;
②:ProxyTransactionManagementConfiguration.class
解释:
①是事物的属性配置的方法
看如下图:
红线标注的是对spring容器加入@Tranction的事务属性进行配置
如下图,进行解析
②昰事务的拦截器的方法
如下图,将事务属性资源的属性设置到事务拦截器方法
## 事务连接器的类以及说明
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
/**
* Create a new TransactionInterceptor.
* <p>Transaction manager and transaction attributes still need to be set.
* @see #setTransactionManager
* @see #setTransactionAttributes(java.util.Properties)
* @see #setTransactionAttributeSource(TransactionAttributeSource)
*/
public TransactionInterceptor() {
}/**
* Create a new TransactionInterceptor.
* @param ptm the default transaction manager to perform the actual transaction management
* @param tas the attribute source to be used to find transaction attributes
* @see #setTransactionManager
* @see #setTransactionAttributeSource(TransactionAttributeSource)
*/
public TransactionInterceptor(PlatformTransactionManager ptm, TransactionAttributeSource tas) {
setTransactionManager(ptm);
setTransactionAttributeSource(tas);
}
@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);
}
}
需要注意的两点:
① 事务拦截器实现了MethodInterceptor接口,这又是在springAOP中提到的拦截器链(https://www.cnblogs.com/dubhlinn/p/10708454.html),追溯一下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来了;
② 构造方法传入PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上面贴的ProxyTransactionManagementConfiguration的源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用set方法注入这两个属性,效果也是一样的。
然后我们继续跟进粉色粗体的invokeWithinTransaction方法的源码,看看触发的方法里面执行了什么
如下图:
① 获取属性解析器,即在ProxyTransactionManagementConfiguration容器配置类中注册事务拦截器时注入的;
②determineTransactionManager方法
spring会先根据qualifier,即@Transactional注解的value属性去获取,但是这个我们一般都不配置,只要在容器中有注册过PlatformTransactionManager类型的事务管理器,就可以直接通过类型来获取
③ 如果目标方法抛异常,会执行completeTransactionAfterThrowing,跟进一下源码:
拿到事务管理器、执行回滚;
④ 如果目标方法正常运行,则会执行commitTransactionAfterReturning,同样跟进一下源码:
总结一下基于注解的声明式事务的原理:
-
在容器配置类上使用@EnableTransactionManagement注解,该注解在容器中注册了两大组件——AutoProxyRegistrar、ProxyTransactionManagementConfiguration;
-
AutoProxyRegistrar通过导入方式在容器中注册了InfrastructureAdvisorAutoProxyCreator,这是一个后置处理器;
-
ProxyTransactionManagementConfiguration本身就是一个容器配置类,它注册了transactionAdvisor(事务增强器),然后又在这个事务增强器中注入了两个属性transactionAttributeSource、transactionInterceptor;
-
transactionAttributeSource用于解析@Transactional注解的各种属性;
-
transactionInterceptor实现了MethodInterceptor,是一个拦截器链,这个拦截器链会从容器中获取事务管理器,利用事务管理器,在目标方法发生异常时执行回滚,在目标发生正常完成后提交事务;
-
第2步的InfrastructureAdvisorAutoProxyCreator后置处理器,会在目标对象创建完成之后将其包装为代理对象,代理对象在执行目标方法时会首先获取拦截器链,这个拦截器链就是第5步的transactionInterceptor。