Spring源码(七)Spring 声明式事务

了解专栏完整的内容,请点击跳转:
Spring Framework专栏导航页

gitee注释版源码


本文对应的流程图

声明式事务完整流程
事务Advisor解析
事务注解匹配

web开发离不开和关系型数据库打交道,最常见的就是MySQL。MySQL目前默认的存储引擎是innodb,他是支持事务的(解决多个数据库操作ACID),那Spring又是如何优雅的实现MySQL的事务呢?

要想实现事务,无非就是在我们的方法内获取数据库连接关闭事务自动提交,待方法执行完进行手动提交或异常时进行回滚。这一系列和业务无关的代码如果都由程序员去操心的话,会出现大量冗余代码,那咋办,AOP呗,对!

Spring还是基于动态代理实现了事务的AOP,同时还定义了七种事务传播行为,使事务嵌套新建挂起融合等更加便捷。


事务传播行为

事务传播行为类型说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起
PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。

事务挂起

事务挂起就是将当前事务的一些信息暂时存起来,待新事务提交或者当前sql执行完后再恢复当前事务继续进行。
在这里插入图片描述

Advisor解析

Spring里的Advisor就是一个特殊的切面Aspect,里边包含了Advise和PointCut。我们在用AspectJ进行自定义AOP处理的时候,是需要自己进行增强代码的编写,那事务注解@Transactional对应的增强代码还需要我们自行编写么?

自然是不需要的,在开启了事务功能后,就已经往Spring里注入了Bean定义,待后面解析advisor时候直接创建出来就行了。

@EnableTransactionManagement
@EnableAspectJAutoProxy(exposeProxy = true) // 可以不用
@ComponentScan(basePackages = {"com.pt"})
public class MainConfig {
	// 此处省略
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class) // 导入了Selector
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(), // 事务(aop)的后置处理器
						ProxyTransactionManagementConfiguration.class.getName()}; // 配置类
			case ASPECTJ:
				return new String[] {determineTransactionAspectClass()};
			default:
				return null;
		}
	}

	private String determineTransactionAspectClass() {
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}

重点看一下导入的这个配置类

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	/**
	 * 事务advisor导入容器中
	 */
	@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;
	}

	/**
	 * 事务属性源对象:用于获取事务属性对象
	 * 用来解析@Transactional
	 * @return
	 */
	@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;
	}

}

看到这里,结合Bean的生命周期,应该能够知道个大概加载流程吧:

  • Spring容器初始化
  • 加载我们的配置类MainClass的bean定义到容器中
  • refresh().invokeBeanFactoryPostProcessors()解析我们的配置类
  • ProxyTransactionManagementConfiguration里用@Bean修饰的方法都被解析成的beanMethods
  • 解析配置类时候通过this.reader.loadBeanDefinitions(configClasses)将@Bean标记的beanMethods注册进bean定义map中,以便之后创建bean
  • createBean时候,会经过一个解析处理Object bean = resolveBeforeInstantiation(beanName, mbdToUse),在这里面会将BeanFactoryTransactionAttributeSourceAdvisor的bean给创建出来
  • 最后在bean初始化之后wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)调用动态代理后置处理器进行切点匹配,找到PointCut,最后创建动态代理。

Advisor匹配

这里的匹配,就是去类中查找是否有@Transactional注解,只要有一个就判定为是需要事务增强的类。每个方法在调用的时候,会再一次用advisor里pointcut的匹配器去匹配,然后拿到增强的拦截器进行增强。

@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				// important!
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//已经被处理过(解析切面时targetSourcedBeans出现过) 就是自己实现创建动态代理逻辑
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
			return bean;
		}
		//不需要增强的
		if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
			return bean;
		}
		//是不是基础的bean 是不是需要跳过的 重复判断 ( 因为循环依赖是可以改变bean的,如果把bean改成了advisor呢)
		if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return bean;
		}

		// 根据当前bean找到匹配的advisor
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		// 当前bean匹配到了advisor
		if (specificInterceptors != DO_NOT_PROXY) {
			// 标记为已处理
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			// 创建我们的真正的代理对象
			Object proxy = createProxy(
					bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}
	@Override
	@Nullable
	protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
		// 进去
		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		// 找到候选的advisor 事务和aspectj的advisor都会解析出来
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 去匹配
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		// 增加一个额外的advisor
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}
	protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

		//用来记录当前正在创建的被代理对象的名称
		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
			 // 从候选的通知器中找到当前Bean关联的advisors
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
			//从线程局部变量中清楚当前正在创建的beanName的代理对象名称
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		// 如果没有 直接返回
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		//定义一个匹配到的增强器集合对象
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		for (Advisor candidate : candidateAdvisors) {
			//判断我们的增强器对象是不是实现了IntroductionAdvisor (很明显我们事务的没有实现 所以不会走下面的逻辑)
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			// 真正的判断我们的事务增强器是不是我们合适的
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		//判断我们事务的增强器BeanFactoryTransactionAttributeSourceAdvisor是否实现了PointcutAdvisor
		else if (advisor instanceof PointcutAdvisor) {
			//转为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;
		}
	}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		Assert.notNull(pc, "Pointcut must not be null");
		// 粗筛 类级别过滤
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

		// 进行方法级别过滤
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		// 判断匹配器是不是IntroductionAwareMethodMatcher  只有AspectJExpressionPointCut才会实现这个接口
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}

		//创建一个集合用于保存targetClass 的class对象
		Set<Class<?>> classes = new LinkedHashSet<>();
		//判断当前class是不是代理的class对象
		if (!Proxy.isProxyClass(targetClass)) {
			//加入到集合中去
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		//获取到targetClass所实现的接口的class对象,然后加入到集合中
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

		// 精筛
		for (Class<?> clazz : classes) {
			//通过class获取到所有的方法
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				//通过methodMatcher.matches来匹配我们的方法
				if (introductionAwareMethodMatcher != null ?
						// 通过切点表达式匹配 aspectj方式
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						// 事务的匹配走这里 通过方法匹配器匹配 接口方式 AbstractFallbackTransactionAttributeSource
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

注意看这里的精筛

@Override
	@Nullable
	public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {

		// 判断method所在的class 是不是Object类型
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// 构建我们的缓存key
		// 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 dta = (DefaultTransactionAttribute) txAttr;
					dta.setDescriptor(methodIdentification);
					dta.resolveAttributeStrings(this.embeddedValueResolver);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				//加入到缓存
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}
@Nullable
	protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// 判断我们的事务方法上的修饰符是不是public的
		// 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);

		// 第一步,我们先去目标class的方法上去找我们的事务注解
		// 新版本只解析当前方法 不会往上找
		// First try is the method in the target class.
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// 第二步:去我们targetClass类[实现类]上找事务注解
		// 当前类没有 ---> 父类  ---> 接口
		// 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;
	}

事务方法调用

@Override
	@Nullable
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;

		// 获取到我们的目标对象
		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			// 若执行代理对象的equals方法不需要代理
			if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
				// The target does not implement the equals(Object) method itself.
				return equals(args[0]);
			}
			// 若执行的是hashCode方法 不需要代理
			else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
				// The target does not implement the hashCode() method itself.
				return hashCode();
			}
			// 若执行的class对象是DecoratingProxy 则不会对其应用切面进行方法的增强。返回源目标类型
			else if (method.getDeclaringClass() == DecoratingProxy.class) {
				// There is only getDecoratedClass() declared -> dispatch to proxy config.
				return AopProxyUtils.ultimateTargetClass(this.advised);
			}
			// 如果目标对象实现的Advised接口,则不会对其应用切面进行方法的增强。 直接执行方法
			else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
					method.getDeclaringClass().isAssignableFrom(Advised.class)) {
				// Service invocations on ProxyConfig with the proxy config...
				return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
			}

			Object retVal;

			/**
			 * 这个配置很重要很实用【暴露我们的代理对象到线程变量中】需要搭配@EnableAspectJAutoProxy(exposeProxy = true) 一起使用.
			 * 在本类中调用本类方法 用AopContext调用 可以走代理
			 * int retVal = ((Calculate) AopContext.currentProxy()).add(numA,numB);
			 */
			if (this.advised.exposeProxy) {
				// 把我们的代理对象暴露到线程变量中
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

			// Get as late as possible to minimize the time we "own" the target,
			// in case it comes from a pool.
			// 获取我们的目标对象
			target = targetSource.getTarget();
			Class<?> targetClass = (target != null ? target.getClass() : null);

			// 把我们的aop的advisor 全部转化为拦截器, 通过责任链模式 依此调用
			// Get the interception chain for this method.
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

			// Check whether we have any advice. If we don't, we can fallback on direct
			// reflective invocation of the target, and avoid creating a MethodInvocation.
			if (chain.isEmpty()) {
				// We can skip creating a MethodInvocation: just invoke the target directly
				// Note that the final invoker must be an InvokerInterceptor so we know it does
				// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
				// 通过反射直接调用执行
				Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
				retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
			}
			else {
				// 创建一个方法调用对象
				// We need to create a method invocation...
				MethodInvocation invocation =
						new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// 调用执行
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}

			// Massage return value if necessary.
			Class<?> returnType = method.getReturnType();
			if (retVal != null && retVal == target &&
					returnType != Object.class && returnType.isInstance(proxy) &&
					!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
				// Special case: it returned "this" and the return type of the method
				// is type-compatible. Note that we can't help if the target sets
				// a reference to itself in another returned object.
				retVal = proxy;
			}
			else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
				throw new AopInvocationException(
						"Null return value from advice does not match primitive return type for: " + method);
			}
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				// Must have come from TargetSource.
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

调用拦截器,进行事务相关的增强流程

@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.
		TransactionAttributeSource tas = getTransactionAttributeSource();

		// 获取解析后的事务属性信息,
		// 创建代理的时候也调用了getTransactionAttribute还记得吗, 如果解析到了事务属性就可以创建代理,
		// 在这里是从解析后的缓存中获取
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		// 获取我们配置的事务管理器对象
		final TransactionManager tm = determineTransactionManager(txAttr);

		if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
			boolean isSuspendingFunction = KotlinDetector.isSuspendingFunction(method);
			boolean hasSuspendingFlowReturnType = isSuspendingFunction &&
					COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName());
			if (isSuspendingFunction && !(invocation instanceof CoroutinesInvocationCallback)) {
				throw new IllegalStateException("Coroutines invocation not supported: " + method);
			}
			CoroutinesInvocationCallback corInv = (isSuspendingFunction ? (CoroutinesInvocationCallback) invocation : null);

			ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
				Class<?> reactiveType =
						(isSuspendingFunction ? (hasSuspendingFlowReturnType ? Flux.class : Mono.class) : method.getReturnType());
				ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(reactiveType);
				if (adapter == null) {
					throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " +
							method.getReturnType());
				}
				return new ReactiveTransactionSupport(adapter);
			});

			InvocationCallback callback = invocation;
			if (corInv != null) {
				callback = () -> CoroutinesUtils.invokeSuspendingFunction(method, corInv.getTarget(), corInv.getArguments());
			}
			Object result = txSupport.invokeWithinTransaction(method, targetClass, callback, txAttr, (ReactiveTransactionManager) tm);
			if (corInv != null) {
				Publisher<?> pr = (Publisher<?>) result;
				return (hasSuspendingFlowReturnType ? KotlinDelegate.asFlow(pr) :
						KotlinDelegate.awaitSingleOrNull(pr, corInv.getContinuation()));
			}
			return result;
		}

		PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
		// 从tx属性对象中获取出标注了@Transactionl的方法描述符
		// 之前往descriptor中设置的还记得吧
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		// 处理声明式事务
		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// 跟进去 有没有必要创建事务
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			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.
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// 抛出异常进行回滚处理
				// target invocation exception
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				// 清空我们的线程变量中transactionInfo的值
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && 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);
				}
			}

			//提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		// 编程式事务:(回调偏向)
		else {
			Object result;
			final ThrowableHolder throwableHolder = new ThrowableHolder();

			// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
			try {
				result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
					TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
					try {
						Object retVal = invocation.proceedWithInvocation();
						if (retVal != null && 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);
					}
				});
			}
			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;
			}

			// Check result state: It might indicate a Throwable to rethrow.
			if (throwableHolder.throwable != null) {
				throw throwableHolder.throwable;
			}
			return result;
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值