Spring事务管理简单原理

Spring事务管理简单原理

1. @EnableTransactionManagement

使用注解 @EnableTransactionManagement 开启事务管理。该注解导入类 TransactionManagementConfigurationSelector.class 。如下所示:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)   // 导入类
public @interface EnableTransactionManagement {
  ...
}

TransactionManagementConfigurationSelector.class 核心代码如下,即导入了两个类:AutoProxyRegistrar.classProxyTransactionManagementConfiguration.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);
}
上一篇:StrutsResultSupport的使用


下一篇:asp.net(C#) 中 怎么使用 MongoDb