Spring框架事务核心源码解析

本文详细剖析了Spring框架的事务管理源码,涵盖@EnableTransactionManagement注解的作用,事务代理对象的创建与调用流程。讲解了7种传播特性的处理逻辑,以及AOP在事务管理中的应用。分析了TransactionInterceptor、TransactionAspectSupport、DataSourceTransactionManager等关键组件的工作原理,揭示了Spring事务管理的内在机制。

详细分析了Spring事务管理的源码,包括7种传播特性在存在事务和不存在事务情况下的处理逻辑,顺带着也把AOP的核心源码也一起分析了。

@EnableTransactionManagement注解分析

事务代理对象的创建AOP代理对象的创建类似,要启动事务管理,需要在配置类上使用@EnableTransactionManagement注解,来看看这个注解做了些什么事情:

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

    //代理对象是否使用CGLIB来创建
	boolean proxyTargetClass() default false;

    //默认使用代理模式
	AdviceMode mode() default AdviceMode.PROXY;

    //默认最低优先级(拦截链上最后执行)
	int order() default Ordered.LOWEST_PRECEDENCE;
}

看看 TransactionManagementConfigurationSelector 这个注册了些什么:

protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
		    //默认PROXY, 导入AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration 。
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			//ASPECTJ的方式会加载 AspectJTransactionManagementConfiguration
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}

AutoProxyRegistrar 会往容器中注册 InfrastructureAdvisorAutoProxyCreator:

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
		...
					//注册 InfrastructureAdvisorAutoProxyCreator 。
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
		...
		
	}

这儿注意一点的是,如果我们同时使用@EnableAspectJAutoProxy这个的话,上一篇文章解析过,它会注册 AnnotationAwareAspectJAutoProxyCreator 这个类型AutoProxyCreator,此时spring会选择一个来注册,具体为AopConfigUtils.registerOrEscalateApcAsRequired 方法:

private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
			@Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        
        //如果已经存在AutoProxyCreator,并且再次注册的class和已经注册的不一致,那么更具优先级进行替换(新注册的优先级高的话,就替换,否则不动)
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
    
        //注册具体的 AutoProxyCreator 。
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

不通过类型的优先级定义:

static {
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}

简言之,如果@EnableAspectJAutoProxy启用的话,AutoProxyRegistrar其实没做啥子事情。

另外一个ProxyTransactionManagementConfiguration,是一个配置类,它主要会配置TransactionAttributeSource 、 TransactionInterceptor、 BeanFactoryTransactionAttributeSourceAdvisor:

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		//注入TransactionAttributeSource
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		//注入TransactionInterceptor
		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() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		//注入TransactionAttributeSource
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

事务代理对象的创建

@EnableTransactionManagement注解会注册 InfrastructureAdvisorAutoProxyCreator 或者使用 @EnableAspectJAutoProxy 的 AnnotationAwareAspectJAutoProxyCreator,无论使用哪一个,他们都继承至AbstractAutoProxyCreator(封装了核心逻辑),都是 InstantiationAwareBeanPostProcessor ,因此在getBean过程中,会触发 AbstractAutoProxyCreator.postProcessBeforeInstantiation 方法,这个方法在上一篇文章已经分析过了,对于我们事务来将,关键一步是

public List<Advisor> findAdvisorBeans() {

        //找到容器中所有的Advisor类型,并将名称缓存到cachedAdvisorBeanNames
        //这就会把前面配置中声明的BeanFactoryTransactionAttributeSourceAdvisor找到了。
		// Determine list of advisor bean names, if not cached already.
    		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the auto-proxy creator apply to them!
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		
		//没有找到返回空列表
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}
        
        //有的话,getBean,然后加入到列表中返回。
		List<Advisor> advisors = new ArrayList<>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				...
				else {
					try {
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					...
				}
			}
		}
		return advisors;
	}

同样,在AbstractAutoProxyCreator.postProcessAfterInitialization 方法中创建代理对象:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
		    //如果有必要的话,包装成代理对象
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

wrapIfNecessary的具体逻辑:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//一些前置校验
		....

        //找到适合当前bean的Advisor
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		
		//如果有当前bean需要增强,则创建代理对象。
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			
			//创建代理对象,具体的创建过程Aop源码分析中已经解析过了。
			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;
	}

代理对象的创建过程在前面AOP源码中已经分析过了,因此重点来看看针对事务的Advisor过程:

protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    //找到适合当前bean的advisor
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	
	//如果为空,没找到,返回DO_NOT_PROXY(null,即不需要代理)
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

findEligibleAdvisors方法:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	//找到所有候选的Advisor。这一步前面已经分析过了,会找到容器中所有的Advisor,这里面就包括了事务的 BeanFactoryTransactionAttributeSourceAdvisor
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	
	//从所有的候选Advisor中找到能应用到当前bean的Advisor
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	
	//合适的Adivsor不为空时,进行优先级排序(具体的排序见AnnotationAwareOrderComparator)
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

findAdvisorsThatCanApply方法

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		//候选会空,知己恩返回空列表
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		
		List<Advisor> eligibleAdvisors = new ArrayList<>();
		
		//IntroductionAdvisor(引入)的处理,通常用的少
	    .....
	    
	    //遍历候选,判断是否和当前bean匹配,匹配的话就加入到合适的列表中。
		for (Advisor candidate : candidateAdvisors) {
    		...
    		//canApply 方法来实现匹配逻辑
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}

canApply 方法:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
		//引入类型的匹配
		if (advisor instanceof IntroductionAdvisor) {
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		
		//PointcutAdvisor 类型的处理,一般这个居多 , BeanFactoryTransactionAttributeSourceAdvisor 这个就是 PointcutAdvisor 。
		else if (advisor instanceof PointcutAdvisor) {
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			
			//匹配逻辑委托给 Pointcut 处理。BeanFactoryTransactionAttributeSourceAdvisor 的 pointCut 为 TransactionAttributeSourcePointcut 。
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		
		//其他,默认匹配。
		else {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

canApply方法(参数是Pointcut的)

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		//首先通过ClassFilter来匹配。TransactionAttributeSourcePointcut 的ClassFilter 是 ClassFilter.TRUE, 恒定返回true的。
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}

        //Pointcut 中获取方法匹配。
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		
		//方法匹配器是特定true对象是,直接返回true,不需要遍历方法去匹配。
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

        
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}
    
        //classes放入自己的class,以及实现的所有接口(包括其父类实现的接口)
		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

        //遍历classes,获取所有方法,遍历方法,使用方法匹配器对方法进行匹配,匹配上了返回true。
		for (Class<?> clazz : classes) {
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				if (introductionAwareMethodMatcher != null ?
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
						methodMatcher.matches(method, targetClass)) {
					return true;
				}
			}
		}

		return false;
	}

返回到TransactionAttributeSourcePointcut这个,发现它就是MethodMatcher:

public final MethodMatcher getMethodMatcher() {
    //TransactionAttributeSourcePointcut 实现了 MethodMatcher
	return this;
}

那么它是如何进行方法匹配的:

public boolean matches(Method method, @Nullable Class<?> targetClass) {
	...
	//匹配的过程委托给TransactionAttributeSource的getTransactionAttribute方法,有返回值就匹配。
	TransactionAttributeSource tas = getTransactionAttributeSource();
	return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

TransactionAttributeSource呢,就是@EnableTransactionManagement注解配置的AnnotationTransactionAttributeSource,它的getTransactionAttribute方法:

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	
        //首先,看看缓存中有没有,
		// First, see if we have a cached value.
		Object cacheKey = getCacheKey(method, targetClass);
		Object cached = this.attributeCache.get(cacheKey);
		
		//缓存中有,如果缓存的是NULL_TRANSACTION_ATTRIBUTE,返回null(前面的mathes方法就会返回false)。
		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;
		}
	}

最后,分析如何从方法上,找到出事务属性的:

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);
        
        //首先,在目标方法上找@Transactional注解,然后解析成TransactionAttribute(通过SpringTransactionAnnotationParser来解析)
		// First try is the method in the target class.
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

        //然后在目标类上找找@Transactional注解,然后解析成TransactionAttribute
		// 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) {
		    
		    //再然后在接口方法上找@Transactional注解,然后解析成TransactionAttribute
			// Fallback is to look at the original method.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			
			//最后在接口上找@Transactional注解,然后解析成TransactionAttribute
			// Last fallback is the class of the original method.
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

        //4个地方都没找到,返回null
		return null;
	}

到此,事务的代理对象就能创建起来了, 接下来分析下事务的调用:

事务代理对象的调用

同样,以JDK动态代理为例,调用代理对象的方法时,会进入到 JdkDynamicAopProxy.invoke 方法:

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

		TargetSource targetSource = this.advised.targetSource;
		Object target = null;

		try {
			//特殊调用处理,如equals、hashCode等。

			Object retVal;

            //暴露代理对象
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}

		    ...
            
            //构建该调用方法的拦截器链
			// 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...
				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.
			....
			
			return retVal;
		}
		finally {
			...
			//解绑暴露的代理对象
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

getInterceptorsAndDynamicInterceptionAdvice 方法逻辑简单,主要是做缓存处理:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
		MethodCacheKey cacheKey = new MethodCacheKey(method);
		//从缓存中获取
		List<Object> cached = this.methodCache.get(cacheKey);
		
		if (cached == null) {
		    //如果没有获取到,则通过advisorChainFactory来构建拦截器链,结果放入缓存。
			cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
					this, method, targetClass);
			this.methodCache.put(cacheKey, cached);
		}
		
		return cached;
	}

那么 DefaultAdvisorChainFactory 的 getInterceptorsAndDynamicInterceptionAdvice 方法是如何来构建方法拦截器链的:

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
			Advised config, Method method, @Nullable Class<?> targetClass) {

		//interceptorList 返回的拦截器链,可以看出,怎么也不会返回null
		List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
		//目标类型
		Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
		//是否有引入
		boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
		//使用DefaultAdvisorAdapterRegistry 这个来进行Advisor到MethodInterceptor的适配。
		AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();

        //遍历所有合适的Advisor,每个Advisor适配成方法拦截器数组。
		for (Advisor advisor : config.getAdvisors()) {
		
		    //PointcutAdvisor的处理,事务的Advisor进入到这个分支
			if (advisor instanceof PointcutAdvisor) {
				
				PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
				if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
				
				    //获取到方法匹配器
					MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
					
					//当前方法是否匹配
					if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
					
					    //如果匹配,则将Advisor适配成MethodInterceptor[]。加入到返回的拦截器链中。
						MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
						...
						else {
						    //
							interceptorList.addAll(Arrays.asList(interceptors));
						}
					}
				}
			}
			//引入advisor的处理
			else if (advisor instanceof IntroductionAdvisor) {
				IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
				if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
					Interceptor[] interceptors = registry.getInterceptors(advisor);
					interceptorList.addAll(Arrays.asList(interceptors));
				}
			}
			//其他的advisor
			else {
				Interceptor[] interceptors = registry.getInterceptors(advisor);
				interceptorList.addAll(Arrays.asList(interceptors));
			}
		}

		return interceptorList;
	}

那么有是如何将Advisor适配成MethodInterceptor[],看看 DefaultAdvisorAdapterRegistry.getInterceptors 方法实现:

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
		List<MethodInterceptor> interceptors = new ArrayList<>(3);
		Advice advice = advisor.getAdvice();
		
		//如果advisor中的advice本身就是MethodInterceptor,那么不用适配,直接返回。 事务的TransactionInterceptor就是MethodInterceptor类型。
		if (advice instanceof MethodInterceptor) {
			interceptors.add((MethodInterceptor) advice);
		}
		
		/**
		this.adapters会初始化这几个适配器。
		registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
		registerAdvisorAdapter(new AfterReturningAdviceAdapter());
		registerAdvisorAdapter(new ThrowsAdviceAdapter());
		*/
		for (AdvisorAdapter adapter : this.adapters) {
		    //满足某个适配器的话,就用这个适配器来适配相应方法拦截器返回。
			if (adapter.supportsAdvice(advice)) {
				interceptors.add(adapter.getInterceptor(advisor));
			}
		}
		if (interceptors.isEmpty()) {
			throw new UnknownAdviceTypeException(advisor.getAdvice());
		}
		//返回
		return interceptors.toArray(new MethodInterceptor[0]);
	}

拦截器链搞定之后,接下来分析下如何调用拦截器的,看看 ReflectiveMethodInvocation.proceed 方法:

public Object proceed() throws Throwable {
        //this.currentInterceptorIndex从-1开始,每次递归调用一次proceed方法后+1。当它等于拦截器数量-1时,表示所有拦截器都已经在递归的调用链上了,最后调用目标方法。
		//	We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			//反射调用目标方法
			return invokeJoinpoint();
		}
        
        //获取当前拦截器(第一次调用get(0),第二次调用 get(1), ...)
		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		
		....
	        
		else {
		    //调用MethodInterceptor的invoke方法,并将this传过去,供拦截器回调proceed()方法,形成递归调用。
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

对于事务来说,使用的是TransactionInterceptor这个方法拦截器,来看看它的invoke方法:

public Object invoke(MethodInvocation invocation) throws Throwable {
		
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

        //调用invokeWithinTransaction模板方法,注意其中的invocation::proceed回调。
		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
	}

整个事务的控制逻辑就在 TransactionAspectSupport.invokeWithinTransaction 方法中

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 是配置的 AnnotationTransactionAttributeSource。
		TransactionAttributeSource tas = getTransactionAttributeSource();
		//获取该方法的事务属性对象,这个在前面创建代理对象的过程中已经分析过了,如果不为null,表示有事务。
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		//获取事务管理器,默认会调用 defaultTransactionManager = this.beanFactory.getBean(PlatformTransactionManager.class); 从容器中获取事务管理器。
		//通常我们会配置一个DataSourceTransactionManager。
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		//获取到方法连接点标识(这个在前面方法匹配的过程中,顺手缓存在事务属性对象中)
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
        
        //这个if块对标准事务进行处理。(注意txAttr == null也会进入,在整个逻辑中,都会对txAttr进行判断)
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
		
		    //如果需要的话,创建并开启事务
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			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 {
			    //清除事务信息
				cleanupTransactionInfo(txInfo);
			}
			//返回前,提交事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}
    
        //CallbackPreferringPlatformTransactionManager这种事务管理器处理,逻辑不复杂,可自己分析下,这儿省略
		else {
			。。。。。
	}

创建并开启事务,createTransactionIfNecessary方法:

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
        
        //txAttr可能会null,因此整个链条上都会对此进行判断。
        
		// If no name specified, apply method identification as transaction name.
		if (txAttr != null && txAttr.getName() == null) {
		    //使用DelegatingTransactionAttribute包装下事务属性对象,重写getName方法,即用方法连接点标识作为事务名称。
			txAttr = new DelegatingTransactionAttribute(txAttr) {
			    
				@Override
				public String getName() {
					return joinpointIdentification;
				}
			};
		}

		TransactionStatus status = null;
		if (txAttr != null) {
			if (tm != null) {
			
			    //通过PlatformTransactionManager.getTransaction 方法,来创建事务状态
				status = tm.getTransaction(txAttr);
			}
			else {
				if (logger.isDebugEnabled()) {
					logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
							"] because no transaction manager has been configured");
				}
			}
		}
		//构建并准备 TransactionInfo 对象。
		return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
	}

通常,我们会使用DataSourceTransactionManager,因此我们分析下它的getTransaction方法(注意该方法位于AbstractPlatformTransactionManager中,典型的模板方法模式):

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
		
		//由子类实现(即DataSourceTransactionManager实现。
		Object transaction = doGetTransaction();

        //如果事务定义为null,则给个默认的。(实际上,通过前面调用进来的都不会为空)
		if (definition == null) {
			// Use defaults if no transaction definition given.
			definition = new DefaultTransactionDefinition();
		}
        
        /**
        如果有事务,就在事务中执行,            如果没有,就新创建事务      required。
        如果有事务,就在事务中执行,            如果没有,就直接中执行      support
        如果有事务,就在事务中执行,            如果没有,就抛出异常	    mandatory
        如果有事务,就挂起事务,新创建事务执行,如果没有,新创建事务执行    requied_new
        如果有事务,就抛出异常,                如果没有,就直接执行        never
        如果有事务,就挂起事务,不在事务中执行,如果没有,就直接执行        not_support
        如果有事务,就开启嵌套子事务执行,      如果没有,新创建事务执行。  nested
        */
        
        //如果已经存在了事务,那么根据不同的事务传播特性,进行不同的处理。
        //判断事务是否存在的标识是当前线程的Threadlocal中能不能获取到ConnectionHolder
		if (isExistingTransaction(transaction)) {
			// Existing transaction found -> check propagation behavior to find out how to behave.
			return handleExistingTransaction(definition, transaction, debugEnabled);
		}

        //事务超时配置校验
		// Check definition settings for new transaction.
		if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
			throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
		}

        //没有存在的事务,检查传播特性,如果是强制当前事务中执行,这抛出异常。(PROPAGATION_MANDATORY是必须有事务,在当前事务中执行)
		// No existing transaction found -> check propagation behavior to find out how to proceed.
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
			throw new IllegalTransactionStateException(
					"No existing transaction found for transaction marked with propagation 'mandatory'");
		}
		
		//没有存在的事务,如果传播特性在是REQUIRED、REQUIRES_NEW、NESTED之一,新创建事务执行
		else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
				definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
				definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			
			//挂起事务,这儿实际上是没有可挂起的事务的,传入null(啥都没做,返回null)
			SuspendedResourcesHolder suspendedResources = suspend(null);
			...
			try {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				
				//创建一个新的事务状态对象,封装了事务定义,事务对象,新事务标识,挂起事务资源信息等。
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				
				//开启事务
				doBegin(transaction, definition);
				
				//如果是新事务,将新事物相关信息放到事务同步管理器中去。
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException | Error ex) {
			    //开启事务异常,恢复挂起的事务。
				resume(null, suspendedResources);
				throw ex;
			}
		}
		//没有存在的事务,SUPPORTS NOT_SUPPORTED  NEVER, 则直接执行(创建空事务对象方式)
		else {
			// Create "empty" transaction: no actual transaction, but potentially synchronization.
			...
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			//不需要在事务中执行时,创建一个默认的空事务状态对象(即其中事务对象为空)
			//虽然是空事务状态,但也是新事务,也会将新事物相关信息放到事务同步管理器中去。
			return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
		}
	}

getTransaction的逻辑较多,也是事务的核心所在,一个一个方法来分析,首先DataSourceTransactionManager.doGetTransaction方法:

protected Object doGetTransaction() {
        //实例化DataSourceTransactionObject对象,这个里面封装了ConnectionHolder等信息。
		DataSourceTransactionObject txObject = new DataSourceTransactionObject();
		
		//设置是否支持内嵌事务(Nested传播特性)的保存点,默认是false的。
		txObject.setSavepointAllowed(isNestedTransactionAllowed());
		
		//从事务同步管理器TransactionSynchronizationManager中获取ConnectionHolder对象,TransactionSynchronizationManager中封装了一些列的ThreadLocal,用于在同一线程中传递事务信息。
		ConnectionHolder conHolder =
				(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());
		
		//ConnectionHolder设置到事务对象中去。
		txObject.setConnectionHolder(conHolder, false);
		return txObject;
	}

TransactionSynchronizationManager的属性介绍:

public abstract class TransactionSynchronizationManager {
    //事务资源信息
	private static final ThreadLocal<Map<Object, Object>> resources =
			new NamedThreadLocal<>("Transactional resources");
    //事务同步器
	private static final ThreadLocal<Set<TransactionSynchronization>> synchronizations =
			new NamedThreadLocal<>("Transaction synchronizations");
    //当前事务名
	private static final ThreadLocal<String> currentTransactionName =
			new NamedThreadLocal<>("Current transaction name");
    //当前事务只读状态
	private static final ThreadLocal<Boolean> currentTransactionReadOnly =
			new NamedThreadLocal<>("Current transaction read-only status");
    //当前事务隔离级别
	private static final ThreadLocal<Integer> currentTransactionIsolationLevel =
			new NamedThreadLocal<>("Current transaction isolation level");
    //当前事务是否真实的事务(有可能是空事务,支持不在事务中执行的情况)
	private static final ThreadLocal<Boolean> actualTransactionActive =
			new NamedThreadLocal<>("Actual transaction active");

开启事务核心方法 DataSourceTransactionManager.doBegin 方法:

protected void doBegin(Object transaction, TransactionDefinition definition) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) transaction;
		Connection con = null;

		try {
		    //新开启事务,ConnectionHolder是null,那么需要新获取连接。
			if (!txObject.hasConnectionHolder() ||
					txObject.getConnectionHolder().isSynchronizedWithTransaction()) {
				//通过连接池获取数据连接
				Connection newCon = obtainDataSource().getConnection();
				//将数据库连接包装成ConnectionHolder,设置到事务对象上。
				txObject.setConnectionHolder(new ConnectionHolder(newCon), true);
			}
            
			txObject.getConnectionHolder().setSynchronizedWithTransaction(true);
			//拿到数据库连接
			con = txObject.getConnectionHolder().getConnection();
            
            //给数据库连接设置事务属性,如是否只读、隔离级别。
            //注意如果事务定义了隔离级别(不是默认的),那么会将连接上原来的隔离级别缓存到txObject中,以便于后面恢复。
			Integer previousIsolationLevel = DataSourceUtils.prepareConnectionForTransaction(con, definition);
			txObject.setPreviousIsolationLevel(previousIsolationLevel);
                
            //设置连接为手动提交。    
			// Switch to manual commit if necessary. This is very expensive in some JDBC drivers,
			// so we don't want to do it unnecessarily (for example if we've explicitly
			// configured the connection pool to set it already).
			if (con.getAutoCommit()) {
				txObject.setMustRestoreAutoCommit(true);
				con.setAutoCommit(false);
			}
            
            //开启事务后对连接的准备处理(如果是只读事务,执行"SET TRANSACTION READ ONLY"语句)
			prepareTransactionalConnection(con, definition
			//将当前事务激活(在判断是否已经存在事务时,会用到这个)
			txObject.getConnectionHolder().setTransactionActive(true);
            
            //事务超时时间确定和设置
			int timeout = determineTimeout(definition);
			if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
				txObject.getConnectionHolder().setTimeoutInSeconds(timeout);
			}

            //如果是新获取的连接,这绑定到事务同步管理器中。
			// Bind the connection holder to the thread.
			if (txObject.isNewConnectionHolder()) {
				TransactionSynchronizationManager.bindResource(obtainDataSource(), txObject.getConnectionHolder());
			}
		}

		catch (Throwable ex) {
		    //开启事务异常处理....
			if (txObject.isNewConnectionHolder()) {
				DataSourceUtils.releaseConnection(con, obtainDataSource());
				txObject.setConnectionHolder(null, false);
			}
			throw new CannotCreateTransactionException("Could not open JDBC Connection for transaction", ex);
		}
	}

开启事务后,返回到createTransactionIfNecessary方法的最后一步prepareTransactionInfo方法,它将开启事务返回的事务状态、事务管理器、事务属性等信息封装成事务信息对象返回:

protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
			@Nullable TransactionAttribute txAttr, String joinpointIdentification,
			@Nullable TransactionStatus status) {

        //新建TransactionInfo对象,将事务管理器、事务属性、方法标识封装进去。
		TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);
		
		//txAttr不为null,表示在新事务中执行
		if (txAttr != null) {
		    ...
			txInfo.newTransactionStatus(status);
		}
		else {
			...
		}
        
        //把TransactionInfo自己绑定到ThreadLocal中。
		// We always bind the TransactionInfo to the thread, even if we didn't create
		// a new transaction here. This guarantees that the TransactionInfo stack
		// will be managed correctly even if no transaction was created by this aspect.
		txInfo.bindToThread();
		return txInfo;
	}

接下来回到 invokeWithinTransaction 方法中,在创建了事务之后,执行retVal = invocation.proceedWithInvocation();,它会回调拦截器链,最终调用目标方法,如果在调用的过程中,有异常抛出,被invokeWithinTransaction方法中的try…catch代码块捕获了,那么会执行completeTransactionAfterThrowing方法,如果都正常执行成功,那么会调用commitTransactionAfterReturning方法。
分别看看这两个方法会是如何执行回滚和提交的:

protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
        //如果在事务中执行..
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
			...
			//对抛出的异常类型检查,如果满足配置的异常类型,这执行回滚(默认异常类型是RuntimeException 和 Error)
			if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
				try {
				    //调用事务管理器的rollback方法,回滚事务
					txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
				}
				...
			}
			//抛出的异常类型不满足配置的异常类型,执行提交。
			else {
				// We don't roll back on this exception.
				// Will still roll back if TransactionStatus.isRollbackOnly() is true.
				try {
				    //调用事务管理器的commit方法,提交事务
					txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
				}
				...
			}
		}
	}
	
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
		 //如果在事务中执行..
		if (txInfo != null && txInfo.getTransactionStatus() != null) {
		    //调用事务管理器的commit方法,提交事务
			txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
		}
	}
	

对于DataSourceTransactionManager这个事务管理器来说,提交和回滚动作最终会调用数据库连接的commit和rollback方法(当然还有很多其他的处理,不展开分析)

protected void doCommit(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		Connection con = txObject.getConnectionHolder().getConnection();
	
		try {
			con.commit();
		}
		...
	}

	@Override
	protected void doRollback(DefaultTransactionStatus status) {
		DataSourceTransactionObject txObject = (DataSourceTransactionObject) status.getTransaction();
		Connection con = txObject.getConnectionHolder().getConnection();

		try {
			con.rollback();
		}
    	...
	}

到此,我们分析了在没有事务情况下,也就是说第一次进入到事务的方法拦截器中的情况。
在存在事务情况下,即事务方法调用另外一个事务方法时,不同的地方位于AbstractPlatformTransactionManager的getTransaction方法中,会进入到handleExistingTransaction分支方法:

private TransactionStatus handleExistingTransaction(
			TransactionDefinition definition, Object transaction, boolean debugEnabled)
			throws TransactionException {
        
        //存在事务,传播特性为NEVER时,抛出异常。
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {
			throw new IllegalTransactionStateException(
					"Existing transaction found for transaction marked with propagation 'never'");
		}
        
        //存在事务,传播特性为NOT_SUPPORTED时,挂起事务,创建一个空事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {
			//挂起当前事务(把当前事务同步管理器中的信息取出,封装到SuspendedResourcesHolder中,这个对象设置新创建的事务状态对象中的一个属性,可以用它来恢复事务)
			Object suspendedResources = suspend(transaction);
			boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
			
			//创建和准备空事务对象
			return prepareTransactionStatus(
					definition, null, false, newSynchronization, debugEnabled, suspendedResources);
		}
        
        //存在事务,传播特性为REQUIRES_NEW时,挂起事务,创建一个新事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
			//挂起当前事务
			SuspendedResourcesHolder suspendedResources = suspend(transaction);
			try {
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				
				//创建新事务状态对象
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
				
				//开启新事务
				doBegin(transaction, definition);
				
				//将新事物相关信息放到事务同步管理器中去。
				prepareSynchronization(status, definition);
				return status;
			}
			catch (RuntimeException | Error beginEx) {
				resumeAfterBeginException(transaction, suspendedResources, beginEx);
				throw beginEx;
			}
		}
        
        //存在事务,传播特性为NESTED时,创建一个内嵌事务
		if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
			...
			//使用JDBC 3.0 savepoints特性来支持内嵌事务
			if (useSavepointForNestedTransaction()) {
				// Create savepoint within existing Spring-managed transaction,
				// through the SavepointManager API implemented by TransactionStatus.
				// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
				DefaultTransactionStatus status =
						prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
				status.createAndHoldSavepoint();
				return status;
			}
			//只支持JTA的内嵌事务
			else {
				// Nested transaction through nested begin and commit/rollback calls.
				// Usually only for JTA: Spring synchronization might get activated here
				// in case of a pre-existing JTA transaction.
				boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
				DefaultTransactionStatus status = newTransactionStatus(
						definition, transaction, true, newSynchronization, debugEnabled, null);
				doBegin(transaction, definition);
				prepareSynchronization(status, definition);
				return status;
			}
		}

        //存在事务,SUPPORTS、REQUIRED、MANDATORY 这几种都是在当前事务中执行。
		// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
		....
		boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
		//使用已有的事务创建事务状态对象返回,注意这儿传入的是false,表示不是新事务。在事务管理器的提交和回滚方法中,会基于此来觉得是否真正的进行提交和回滚。
		return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
	}

Spring实现事务的原理不复杂,简单来说就是使用AOP机制,提供了Advisor,Advice和方法拦截器的实现,但通过上面的源码分析,感觉又非常繁琐,究其原因是spring提供了7中事务的传播特性,算存在事务和不存在事务的情况,因此一共有14个分支,很容易就会让人晕晕乎乎,不过理解了原理,在debug两遍,基本上也没有什么难度了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值