Spring事务管理简单原理
1. @EnableTransactionManagement
使用注解 @EnableTransactionManagement 开启事务管理。该注解导入类 TransactionManagementConfigurationSelector.class 。如下所示:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class) // 导入类
public @interface EnableTransactionManagement {
...
}
TransactionManagementConfigurationSelector.class 核心代码如下,即导入了两个类:AutoProxyRegistrar.class 和 ProxyTransactionManagementConfiguration.class
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
// 默认导入了两个类
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
总结:注解 @EnableTransactionManagement 向容器中导入类两个类:
- AutoProxyRegistrar.class
- ProxyTransactionManagementConfiguration.class
2. AutoProxyRegistrar.class
该类实现了接口 ImportBeanDefinitionRegistrar ,是一个bean定义的注册器,用来向容器中注册了 InfrastructureAdvisorAutoProxyCreator.class :
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
// 默认注册了InfrastructureAdvisorAutoProxyCreator.class
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
进入方法 AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry) ,会来来到如下代码:
public static BeanDefinition registerAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 注册了类的定义
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
而这个类 InfrastructureAdvisorAutoProxyCreator 是一个后置处理器,在对象初始化完成后进行包装创建代理对象,原理与AOP基本相同。
总结:类 AutoProxyRegistrar 向容器注册了后置处理器 InfrastructureAdvisorAutoProxyCreator, 后置处理器在对象初始化后包装生成代理对象。
3. ProxyTransactionManagementConfiguration.class
这是一个配置类,主要往容器中注册了一些组件:
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
/** 注册了一个事务增强器 */
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
// 创建一个事务增强器
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
// 设置事务属性
advisor.setTransactionAttributeSource(transactionAttributeSource);
// 设置事务拦截器
advisor.setAdvice(transactionInterceptor);
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor;
}
/** 注册事务属性 */
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
/** 注册事务拦截器 */
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
// 设置事务属性
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
// 设置事务管理器
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
事务增强器主要设置了两个组件:AnnotationTransactionAttributeSource (事务属性)和 TransactionInterceptor (事务拦截器)
AnnotationTransactionAttributeSource :主要包含了一些事务属性的解析器,用来对事务注解的属性进行解析。
TransactionInterceptor :包含了事务属性和事务管理器。是一个 MethodInterceptor 方法拦截器。在目标方法执行时会invoke方法。
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
进入方法 invokeWithinTransaction(),主要逻辑如下 :
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
// 获取事务注解属性
TransactionAttributeSource tas = getTransactionAttributeSource();
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 确定事务管理器
final TransactionManager tm = determineTransactionManager(txAttr);
......
// 如果有必要创建事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
try {
// 执行目标方法
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// 如果目标方法抛异常,回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
......
// 提交事务
commitTransactionAfterReturning(txInfo);
}