Spring源码分析十五:事务实现② - ProxyTransactionManagementConfiguration

文章目录

  • 一、前言
  • 二、 ProxyTransactionManagementConfiguration
    • 1. BeanFactoryTransactionAttributeSourceAdvisor
      • 1.1. TransactionAttributeSourcePointcut
    • 2. AnnotationTransactionAttributeSource
      • 2.1 AnnotationTransactionAttributeSource#isCandidateClass
      • 2.2 AbstractFallbackTransactionAttributeSource#getTransactionAttribute
        • 2.2.1 AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method)
        • 2.2.2 SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)
    • 3. TransactionInterceptor
      • 1. TransactionAspectSupport#invokeWithinTransaction

一、前言

本文是笔者阅读Spring源码的记录文章,由于本人技术水平有限,在文章中难免出现错误,如有发现,感谢各位指正。在阅读过程中也创建了一些衍生文章,衍生文章的意义是因为自己在看源码的过程中,部分知识点并不了解或者对某些知识点产生了兴趣,所以为了更好的阅读源码,所以开设了衍生篇的文章来更好的对这些知识点进行进一步的学习。

全集目录:Spring源码分析:全集整理


由于 事务的源码和 前篇的 Aop 源码逻辑很类似,所以本篇中某些内容不会展开去讲解,建议先阅读完 Spring源码分析十一:@AspectJ方式的AOP再来阅读本文会更好理解。


这是一个巨长的篇章…
全集目录如下:

  1. Spring源码分析十四:事务实现① - AutoProxyRegistrar
  2. Spring源码分析十五:事务实现② - ProxyTransactionManagementConfiguration
  3. Spring源码分析十六:事务实现③ - 事务的创建
  4. Spring源码分析十七:事务实现④ - 事务的回滚
  5. Spring源码分析十八:事务实现⑤ - 事务的提交

二、 ProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration 代码如下,并没有逻辑,就是将几个Bean注入的到容器中。不过这几个bean可都是关键bean。

@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;
	}

}
  • BeanFactoryTransactionAttributeSourceAdvisor : 事务的增强器,该方法是否开始事务,是否需要代理该类都在该类中判断
  • TransactionAttributeSource : 保存了事务相关的一些信息资源。
  • TransactionInterceptor : 事务拦截器,事务生成代理类时使用的代理拦截器,编写了事务的规则

1. BeanFactoryTransactionAttributeSourceAdvisor

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

	@Nullable
	private TransactionAttributeSource transactionAttributeSource;

	private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		@Nullable
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};


	/**
	 * Set the transaction attribute source which is used to find transaction
	 * attributes. This should usually be identical to the source reference
	 * set on the transaction interceptor itself.
	 * @see TransactionInterceptor#setTransactionAttributeSource
	 */
	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		this.transactionAttributeSource = transactionAttributeSource;
	}

	/**
	 * Set the {@link ClassFilter} to use for this pointcut.
	 * Default is {@link ClassFilter#TRUE}.
	 */
	public void setClassFilter(ClassFilter classFilter) {
		this.pointcut.setClassFilter(classFilter);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

}

这个根据上面的分析,我们可以知道这个是事务判断的核心,通过 Aop文章的分析我们可以知道,Advisor 判断一个方法是否匹配,是通过其 Pointcut.matchs 属性来判断的。
然后我们通过上面的代码,发现其 Pointcut 的实现类是 TransactionAttributeSourcePointcut

1.1. TransactionAttributeSourcePointcut

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

	protected TransactionAttributeSourcePointcut() {
		setClassFilter(new TransactionAttributeSourceClassFilter());
	}


	@Override
	public boolean matches(Method method, Class<?> targetClass) {
		// 调用 TransactionAttributeSource.getTransactionAttribute方法来匹配
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}

	... 省略一些无关代码
	
	/**
	 * Obtain the underlying TransactionAttributeSource (may be {@code null}).
	 * To be implemented by subclasses.
	 */
	@Nullable
	protected abstract TransactionAttributeSource getTransactionAttributeSource();

	/**
	 * {@link ClassFilter} that delegates to {@link TransactionAttributeSource#isCandidateClass}
	 * for filtering classes whose methods are not worth searching to begin with.
	 */
	private class TransactionAttributeSourceClassFilter implements ClassFilter {

		@Override
		public boolean matches(Class<?> clazz) {
			// 如果是一些基础类,则返回false
			if (TransactionalProxy.class.isAssignableFrom(clazz) ||
					PlatformTransactionManager.class.isAssignableFrom(clazz) ||
					PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
				return false;
			}
			// 调用 TransactionAttributeSource.isCandidateClass 方法来匹配
			TransactionAttributeSource tas = getTransactionAttributeSource();
			return (tas == null || tas.isCandidateClass(clazz));
		}
	}

}

Aop中我们总结了 Pointcut 匹配的需要满足下面两个条件:

  1. pc.getClassFilter().matches(targetClass) 返回true
  2. pc.getMethodMatcher().matches(method, targetClass) 返回true

通过 TransactionAttributeSourcePointcut 的代码我们可以发现,上面两个条件的关键
可以转换成

  1. 调用 TransactionAttributeSource.isCandidateClass 方法来匹配
  2. 调用 TransactionAttributeSource.getTransactionAttribute方法来匹配

TransactionAttributeSource 正是我们在 ProxyTransactionManagementConfiguration中注入的 AnnotationTransactionAttributeSource

2. AnnotationTransactionAttributeSource

经过上面的分析,我们知道了主要逻辑在 isCandidateClassgetTransactionAttribute 方法中,因此我们下面来看看这两个方法的实现

2.1 AnnotationTransactionAttributeSource#isCandidateClass

isCandidateClass 主要是 判断是否是候选类,即当前的的注解解析器annotationParsers 是否可以解析当前类。annotationParsers 的初始化在其构造函数中,在初始化的过程中中添加了 SpringTransactionAnnotationParser,我们后面的事务注解解析就是通过 SpringTransactionAnnotationParser 进行的解析。

	private final Set<TransactionAnnotationParser> annotationParsers;
	...
	
	public AnnotationTransactionAttributeSource() {
		this(true);
	}
	...
	public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
		this.publicMethodsOnly = publicMethodsOnly;
		if (jta12Present || ejb3Present) {
			this.annotationParsers = new LinkedHashSet<>(4);
			this.annotationParsers.add(new SpringTransactionAnnotationParser());
			if (jta12Present) {
				this.annotationParsers.add(new JtaTransactionAnnotationParser());
			}
			if (ejb3Present) {
				this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
			}
		}
		else {
			this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
		}
	}
	
	@Override	
	public boolean isCandidateClass(Class<?> targetClass) {
		for (TransactionAnnotationParser parser : this.annotationParsers) {
			if (parser.isCandidateClass(targetClass)) {
				return true;
			}
		}
		return false;
	}

2.2 AbstractFallbackTransactionAttributeSource#getTransactionAttribute

getTransactionAttribute 方法的实现在其父类AbstractFallbackTransactionAttributeSource 中 实现的

// 获取事务属性,如果
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// 判断声明类是否是 Object 
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// First, see if we have a cached value.
		// 尝试从缓冲中获取
		Object cacheKey = getCacheKey(method, targetClass);
		TransactionAttribute 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 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.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}

	...	
	// 解析事务注解属性
	protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// Don't allow no-public methods as required.
		// 如果只允许解析public 方法 && 当前方法不是 publissh
		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  方法代表实现类中的方法
		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;
	}

这里的逻辑还是很清楚的

  1. 从实现类方法上获取事务注解,若获取到则返回
  2. 从实现类上获取事务注解,若获取到则返回
  3. 如果存在接口方法,则从接口方法中获取事务注解,若获取到则返回
  4. 若仍未获取到,则返回null,认为当前方法没有被注解修饰

2.2.1 AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method)

在上面的代码中,我们注意到一个方法 findTransactionAttribute。上面代码就是通过 findTransactionAttribute 方法来寻找事务注解属性的。而findTransactionAttribute 的实现在 AnnotationTransactionAttributeSource 中。其实现代码如下

	protected TransactionAttribute findTransactionAttribute(Method method) {
		return determineTransactionAttribute(method);
	}
	
	...
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		for (TransactionAnnotationParser parser : this.annotationParsers) {
			TransactionAttribute attr = parser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}

可以看到 AnnotationTransactionAttributeSource 中获取 事务注解是通过 TransactionAnnotationParser#parseTransactionAnnotation方法去解析的,而一开始我们就说过annotationParsers 在构造函数中添加了SpringTransactionAnnotationParser。我们来看看 SpringTransactionAnnotationParser 进行了怎么样的解析

2.2.2 SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)

到这里,我们终于看到了事务注解的描述,这里就是解析事务注解的各种属性信息了

	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		// 获取事务注解的属性信息
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}
	
....
	// 解析事务注解,并返回
	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"));

		List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
		for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
			rollbackRules.add(new RollbackRuleAttribute(rbRule));
		}
		for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
			rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
		}
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}

我们的分析到这里,就已经可以知道了Spring 中对事务注解的解析过程,逻辑基本和 Spring Aop 类似。

  1. @EnableTransactionManagement 通过引入 TransactionManagementConfigurationSelector 注册了 AutoProxyRegistrarProxyTransactionManagementConfiguration 两个类。
  2. AutoProxyRegistrar 中注册了 InfrastructureAdvisorAutoProxyCreator 自动代理创建器
  3. InfrastructureAdvisorAutoProxyCreator 中拦截bean的创建过程,通过 BeanFactoryTransactionAttributeSourceAdvisor 来判断bean中是否有事务注解,有则进行代理。

在上面的逻辑中,我们似乎没有发现Spring事务代理的具体过程,实际上代理的过程是在 TransactionInterceptor 中。

3. TransactionInterceptor

在 Aop 的分析文章中,我们知道了无论是 Jdk代理还是 Cglib代理,其增强实现都是调用 Advisor 中的Advice 实现。BeanFactoryTransactionAttributeSourceAdvisor 作为 Advisor 的实现类,自然要遵从 Advisor 的处理方式,当代理被调用时会调用这个类的增强方法,也就是此bean 的Advice ,而在解析事务标签是,我们把 TransactionInterceptor 注入到了 BeanFactoryTransactionAttributeSourceAdvisor 中,所以调用事务增强器增强代理类的时会首先执行TransactionInterceptor 进行增强,同时也就是 TransactionInterceptor#invoke 完成了整个事务的逻辑。

所以我们这里自然要看 TransactionInterceptor#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 方法中,这里调用的 invokeWithinTransaction 方法 实际是 TransactionAspectSupport#invokeWithinTransaction 方法。所以下面我们来看看 TransactionAspectSupport#invokeWithinTransaction 方法的具体实现

1. TransactionAspectSupport#invokeWithinTransaction

	@Nullable
	protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		// 获取事务数据源,这里获取的数据源就是在  TransactionInterceptor 注入的时候的设置的属性transactionAttributeSource = AnnotationTransactionAttributeSource。
		// 在 ProxyTransactionManagementConfiguration 中完成	
		TransactionAttributeSource tas = getTransactionAttributeSource();
		// 1. 获取对应的事务属性
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		// 2. 获取一个合适的 TransactionManager 
		final TransactionManager tm = determineTransactionManager(txAttr);
		// 3. 对于反应式事务的处理
		// 从Spring Framework 5.2 M2开始,Spring通过ReactiveTransactionManagerSPI 支持响应式/反应式事务管理
		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
				if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
					throw new TransactionUsageException(
							"Unsupported annotated transaction on suspending function detected: " + method +
							". Use TransactionalOperator.transactional extensions instead.");
				}
				ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
				if (adapter == null) {
					throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
							method.getReturnType());
				}
				return new ReactiveTransactionSupport(adapter);
			});
			return txSupport.invokeWithinTransaction(
					method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
		}
		// 判断 tm是否是 PlatformTransactionManager 类型,是则强转,不是则抛出异常
		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		// 构造方法的唯一标识( 全路径了类名.方法)
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		// 4. 对不同事务情景的处理
		// 声明式事务的处理
		// 如果txAttr为空或者tm 属于非CallbackPreferringPlatformTransactionManager,执行目标增强
		// 在TransactionManager上,CallbackPreferringPlatformTransactionManager实现PlatformTransactionManager接口,暴露出一个方法用于执行事务处理中的回调
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			// 5.如果有必要,创建事务信息。主要由于事务的传播属性,所以这里并不一定会创建事务
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

			Object retVal;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				// 6. 执行被增强的方法
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				// 7. 异常回滚
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// 8. 提交之前清除事务信息
				cleanupTransactionInfo(txInfo);
			}

			if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}
			// 9.提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}
		// 编程式事务(CallbackPreferringPlatformTransactionManager)的处理。这里的逻辑基本都被封装了
		else {
			final ThrowableHolder throwableHolder = new ThrowableHolder();
			try {
				// 直接调用execute 方法。由于事务的提交回滚等操作都已经封装好了,所以这里并没有对事务进行详细的操作。
				Object result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
					// 准备事务信息
					TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
					try {
						// 执行方法
						Object retVal = invocation.proceedWithInvocation();
						if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
							// Set rollback-only in case of Vavr failure matching our rollback rules...
							retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
						}
						return retVal;
					}
					catch (Throwable ex) {
						if (txAttr.rollbackOn(ex)) {
							// A RuntimeException: will lead to a rollback.
							if (ex instanceof RuntimeException) {
								throw (RuntimeException) ex;
							}
							else {
								throw new ThrowableHolderException(ex);
							}
						}
						else {
							// A normal return value: will lead to a commit.
							throwableHolder.throwable = ex;
							return null;
						}
					}
					finally {		
						// 清除事务信息	
						cleanupTransactionInfo(txInfo);
					}
				});

				// Check result state: It might indicate a Throwable to rethrow.
				if (throwableHolder.throwable != null) {
					throw throwableHolder.throwable;
				}
				return result;
			}
			catch (ThrowableHolderException ex) {
				throw ex.getCause();
			}
			catch (TransactionSystemException ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
					ex2.initApplicationException(throwableHolder.throwable);
				}
				throw ex2;
			}
			catch (Throwable ex2) {
				if (throwableHolder.throwable != null) {
					logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
				}
				throw ex2;
			}
		}
	}

从上面的代码中,我们可以知道Spring支持声明式事务和编程式事务两种处理。两者的实现本质基本相同。在invoke方法中我们也可以看到这两种方式的实现,通常我们使用的都是通过 @Transactional 注解修饰的声明式事务,所以我们下面主要分析 声明式事务 的处理过程。

  1. 获取事务属性 TransactionAttributeTransactionAttribute 中包含 传播属性timeout 等事务属性信息。如果是使用 @Transactional 注解,这个解析过程是在AnnotationTransactionAttributeSource#findTransactionAttribute(java.lang.reflect.Method) 中完成,具体看 篇2中有解释。

  2. 加载配置中的 TrancationManager, 事务管理器,是事务实现的基础,我们这里获取到的是 DataSourceTransactionManager

  3. 对反应式事务的处理。

  4. 不同事务处理方式使用不同的逻辑。在上面的代码中主要是两种情况,一是声明式事务,这种情况是通过 @Transactional 注解修饰方法来表示开启事务。另一种情况是编程式事务,即可以通过xml方式或者配置类方式来进行完成事务功能,其实TransactionTemplate 的实现就是编程式事务,但通过 TransactionTemplate 并不会走到这个逻辑,这里的编程式事务应该单独是通过xml或者配置类方式来配置的。

    对于声明式事务的处理和编程式事务的处理,区别主要在两点。一是事务属性上,因为编程式事务是不需要事务属性的,二是 TransactionManager 的不同,CallbackPreferringPlatformTransactionManager 实现了 PlatformTransactionManager 接口,暴露了一个方法用于执行事务处理中的回调。所以这两种方式都可以作为事务处理方式的判断。

  5. 在目标方法执行前获取事务并收集事务信息。

    事务信息与事务属性并不相同,也就是 TransactionInfoTransactionAttribute 并不相同,TransactionInfo 中包含TransactionAttribute 信息,并且处理 TransactionAttribute 之外还有其他事物信息,比如PlatformTransactionManager 以及 TransactionStatus相关信息。

  6. 执行目标方法

  7. 如果出现异常,则进行回滚。这里需要注意,默认的情况下只有 RuntimeException 异常才会执行回滚。可以通过 @Transactional(rollbackFor = Exception.class) 的方式来指定触发回滚的异常

  8. 提交事务前的事务信息清除

  9. 提交事务

  10. 若是 编程式事务,则直接执行execute方法即可,这里就不再讲解。


注: PlatformTransactionManagerReactiveTransactionManager 二者都是为了实现事务,PlatformTransactionManager 在内部进行事务执行流程的封装,并且暴露出来一个 execute 方法用于执行事务的具体信息,TransactionTemplate 的声明式事务就是基于此实现的。而 ReactiveTransactionManager 则是比较原始的,需要我们自己来实现事务的整个逻辑。


上面比较笼统的讲了事务的实现,下面们主要分析以下三个方法,也是事务的的关键流程:
由于篇幅问题,这里另开新篇:

  • 事务的创建 - createTransactionIfNecessary
  • 事务的回滚 - completeTransactionAfterThrowing
  • 事务的提交 - commitTransactionAfterReturning

敬请期待。。。。


以上:内容部分参考
《Spring源码深度解析》
如有侵扰,联系删除。 内容仅用于自我记录学习使用。如有错误,欢迎指正

你可能感兴趣的:(#,源码分析篇)