Spring事务源码解析

Spring的事务属于逻辑事务。不是物理事务。
Spring并不直接管理事务,而是提供了多种事务管理器,它们将事务管理的职责委托给JDBC或者JTA等持久化机制所提供的相关平台框架的事务来实现。例如JDBC的事物管理器就是DataSourceTransactionManager
  Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager

public interface PlatformTransactionManager {
	TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException;
	void commit(TransactionStatus status) throws TransactionException;
	void rollback(TransactionStatus status) throws TransactionException;
}

通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了。所以Spring事务管理的一个优点就是为不同的事务API提供一致的编程模型。

Spring Boot 使用事务非常简单,需要@EnableTransactionManagement@Transactional配合使用。首先使用注解@EnableTransactionManagement 开启事务支持后,然后在Service方法上添加注解@Transactional便可。@EnableTransactionManagement,启注解事务管理等同于xml配置方式的

首先是EnableTransactionManagement类:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

这里会import TransactionManagementConfigurationSelector类:

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
			  // 默认就是 PROXY
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}
}

selectImports会返回两个类:AutoProxyRegistrarProxyTransactionManagementConfiguration

  • AutoProxyRegistrar的作用就是向BeanFactory注册InfrastructureAdvisorAutoProxyCreator.class。而InfrastructureAdvisorAutoProxyCreator继承自AbstractAdvisorAutoProxyCreator,就是让容器支持了AOP。

  • ProxyTransactionManagementConfiguration会加载关键的几个bean:

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		advisor.setAdvice(transactionInterceptor());
		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() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}
  • BeanFactoryTransactionAttributeSourceAdvisor:实现了 PointcutAdvisor 接口,组合了TransactionAttributeSourcePointcut。
  • AnnotationTransactionAttributeSource:解析事务类,得到事务配置相关信息;
  • TransactionInterceptor:事务拦截器,实现了 Advice、MethodInterceptor 接口。TransactionInterceptor是个环绕增强,在目标方法执行前开启事务,执行完目标方法后,进行事务提交或者回滚;

事务代理类的创建

了解Spring AOP应该会熟悉这段代码:

	public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

在前面 BeanFactoryTransactionAttributeSourceAdvisor 类,该类实现了 PointcutAdvisor 接口,其中的切面 pointcut 便是通过 TransactionAttributeSourcePointcut 来实现的。

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
	private TransactionAttributeSource transactionAttributeSource;
	private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};
}

调用路径会到TransactionAttributeSourcePointcut的matches方法,该方法根据能否可以从目标 bean 中得到 TransactionAttribute 来判断是否匹配的。

public boolean matches(Method method, @Nullable Class<?> targetClass) {
	if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
		return false;
	}
	TransactionAttributeSource tas = getTransactionAttributeSource();
	return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

上面的tas即AnnotationTransactionAttributeSource。AnnotationTransactionAttributeSource父类AbstractFallbackTransactionAttributeSource实现了getTransactionAttribute方法:

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	if (method.getDeclaringClass() == Object.class) {
		return null;
	}

	// First, see if we have a cached value.
	Object cacheKey = getCacheKey(method, targetClass);
	Object cached = this.attributeCache.get(cacheKey);
	if (cached != null) {
		// Value will either be canonical value indicating there is no transaction attribute,
		// or an actual transaction attribute.
		if (cached == NULL_TRANSACTION_ATTRIBUTE) {
			return null;
		}
		else {
			return (TransactionAttribute) cached;
		}
	}
	else {
		// We need to work it out.
		//重点,获取事务属性
		TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
		// Put it in the cache.
		if (txAttr == null) {
			this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
		}
		else {
			String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
			if (txAttr instanceof DefaultTransactionAttribute) {
				((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
			}
			this.attributeCache.put(cacheKey, txAttr);
		}
		return txAttr;
	}
}

再看看computeTransactionAttribute方法:

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	// Don't allow no-public methods as required.
	if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
		return null;
	}

	// The method may be on an interface, but we need attributes from the target class.
	// If the target class is null, the method will be unchanged.
	Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

	// First try is the method in the target class.
	//先查找目标方式是否有事务属性
	TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
	if (txAttr != null) {
		return txAttr;
	}

	// Second try is the transaction attribute on the target class.
	//再查找目标类是否有事务属性
	txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
	if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
		return txAttr;
	}

	if (specificMethod != method) {
		// Fallback is to look at the original method.
		txAttr = findTransactionAttribute(method);
		if (txAttr != null) {
			return txAttr;
		}
		// Last fallback is the class of the original method.
		txAttr = findTransactionAttribute(method.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}
	}

	return null;
}

从上面可知,方法级别上的注解会覆盖类级别上的注解,两个findTransactionAttribute方法都在AnnotationTransactionAttributeSource实现,

protected TransactionAttribute findTransactionAttribute(Method method) {
	return determineTransactionAttribute(method);
}


protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
	return determineTransactionAttribute(clazz);
}

再看看determineTransactionAttribute方法:

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
	for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
		TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
		if (attr != null) {
			return attr;
		}
	}
	return null;
}

annotationParsers集合包含了3个类,分别是SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser。分别解析不同包的注解,这里的解析类是SpringTransactionAnnotationParser,其parseTransactionAnnotation方法:

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
	AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
			ae, Transactional.class, false, false);
	if (attributes != null) {
		return parseTransactionAnnotation(attributes);
	}
	else {
		return null;
	}
}

以上代码讲解析目标元素上@Transactional注解的相关信息,然后封装成AnnotationAttributes类,其继承LinkedHashMap。

看看parseTransactionAnnotation方法:

	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		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<RollbackRuleAttribute>();
		Class<?>[] rbf = attributes.getClassArray("rollbackFor");
		for (Class<?> rbRule : rbf) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		String[] rbfc = attributes.getStringArray("rollbackForClassName");
		for (String rbRule : rbfc) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
		for (Class<?> rbRule : nrbf) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
		for (String rbRule : nrbfc) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		rbta.getRollbackRules().addAll(rollBackRules);
		return rbta;
	}

切面实现

TransactionInterceptor 实现了方法拦截器 MethodInterceptor 接口,用于对业务类进行事务增强。TransactionInterceptor 的 invoke 方法主要是调用了父类 TransactionAspectSupport 的 invokeWithinTransaction 方法。

	@Override
	public Object invoke(final MethodInvocation invocation) throws Throwable {
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
		return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
			@Override
			public Object proceedWithInvocation() throws Throwable {
				return invocation.proceed();
			}
		});
	}
	protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation) throws Throwable {
		// 获取事务配置信息
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		// 获取事务管理器
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		// 同步操作
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// 创建事务类
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// 环绕增强:触发链条上的下一个拦截器,最终会调用目标类
				retVal = invocation.proceedWithInvocation();
			} catch (Throwable ex) {
				// 出现异常则回滚
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			} finally {
				cleanupTransactionInfo(txInfo);
			}
			commitTransactionAfterReturning(txInfo);
			return retVal;
		} else {
			// 省略异步操作,原理类似
		}
	}

invoke 方法里主要做以下几件事:

  1. 获取事务属性;
  2. 获取事务管理器;
  3. 创建事务;
  4. 执行目标方法;
  5. 遇到异常则回滚,正常结束则提交。

创建事务的是TransactionAspectSupport#createTransactionIfNecessary()方法,该方法的调用代码比较多,主要摘取比较重要的看一下:

---+TransactionAspectSupport:createTransactionIfNecessary();
   `---+AbstractPlatformTransactionManager:getTransaction();
       +---AbstractPlatformTransactionManager:doGetTransaction();
       `---+AbstractPlatformTransactionManager:doBegin();
           +---DataSource:getConnection();
           `---TransactionSynchronizationManager.bindResource();

参考:

https://blog.csdn.net/wang704987562/article/details/88913808
https://blog.csdn.net/ai_xiangjuan/article/details/79687560
https://blog.csdn.net/u012562943/article/details/78333153
https://www.coder4.com/archives/5917
https://blog.csdn.net/dslztx/article/details/46636079

你可能感兴趣的:(Spring,spring)