详细分析了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两遍,基本上也没有什么难度了。
本文详细剖析了Spring框架的事务管理源码,涵盖@EnableTransactionManagement注解的作用,事务代理对象的创建与调用流程。讲解了7种传播特性的处理逻辑,以及AOP在事务管理中的应用。分析了TransactionInterceptor、TransactionAspectSupport、DataSourceTransactionManager等关键组件的工作原理,揭示了Spring事务管理的内在机制。
2696

被折叠的 条评论
为什么被折叠?



