文章目录
(一)spring事务入口
通常Spring事务开启是从配置文件或Springboot类型的注解模式,本次主要是分析xml配置文件类型的事务,开启入口为:<tx:annotation-driven />
TxNamespaceHandler类开启事务:
public void init() {
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());//tx事务开启入口
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
spring容器解析时,遇到该配置会使用AnnotationDrivenBeanDefinitionParser类中的parse方法进行解析:<tx:annotation-driven transaction-manager="transactionManager" mode="aspectj"/>
,parse方法会对该标签属性逐个解析配置,如事务切入方式mode="aspectj"或"proxy"属性。Spring默认切入方式为代理proxy,可通过mode属性指定事务支持方式。
public BeanDefinition parse(Element element, ParserContext parserContext) {
registerTransactionalEventListenerFactory(parserContext);
String mode = element.getAttribute("mode");//事务切入方式处理
if ("aspectj".equals(mode)) {
// spring aop模式切入方式 mode="aspectj"
registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
} else {
// spring默认事务切入方式:代理 mode="proxy"
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
(二)Spring事务切入方式
Spring默认的事务切入方式:AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
主要针对这行代码开始展开,先讲下该行代码中的处理逻辑。
核心逻辑思想:
- (1)
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
是否需要注册InfrastructureAdvisorAutoProxyCreator事务自动代理器bean; - (2)创建三个bean,分别为TransactionAttributeSource类型的bean即sourceDef、TransactionInterceptor类型的bean即interceptorDef和TransactionAttributeSourceAdvisor类型的bean即advisorDef;
- (3)将前面两个bean即sourceDef、interceptorDef分别以transactionAttributeSource和adviceBeanName属性注入到第三个bean即advisorDef中;
- (4)将第三个bean即advisorDef注册到
TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor"
类型的bean中并注册到容器中。
逻辑示意图:
具体实现代码如下:
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 创建事务自动代理器 InfrastructureAdvisorAutoProxyCreator,使用该类作为名为AUTO_PROXY_CREATOR_BEAN_NAME的bean自动代理器
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
// TRANSACTION_ADVISOR_BEAN_NAME = "org.springframework.transaction.config.internalTransactionAdvisor",创建此类型的bean
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {//容器中不包含该类型的bean时则创建
Object eleSource = parserContext.extractSource(element);
// 创建 TransactionAttributeSource 类型的bean即BeanDefinition
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册到spring中时使用,利用spring生成beanName的规则生成 TransactionAttributeSource 的bean名称
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// 创建 TransactionInterceptor 类型的bean即BeanDefinition
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registerTransactionManager(element, interceptorDef);
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 注册到spring中时使用,利用spring生成beanName的规则生成 TransactionInterceptor 的bean名称
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// 创建 TransactionAttributeSourceAdvisor 类型的bean即BeanDefinition
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 将sourceName类型的bean注入到advisorDef的属性transactionAttributeSource中
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 将interceptorName类型的bean注入到advisorDef的属性adviceBeanName中
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
// 该标签是否配置了oder属性,处理该排序属性
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
// 将生成的advisorDef的bean作为txAdvisorBeanName类型的bean的值注册到容器中
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
// 创建CompositeComponentDefinition类型的bean即BeanDefinition
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);//将其注册到容器中
}
}
}
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
是注册事务代理器的入口,委托给AopNamespaceUtils进行封装,spring很多小功能细节都是交于其他类辅助实现,高度体现函数的封装性,也是优秀框架的方面之一,下面开始深入分析事务代理器,逻辑如下:
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
委托AopConfigUtils->registerAutoProxyCreatorIfNecessary来注册自动代理器,其中使用InfrastructureAdvisorAutoProxyCreator.class
作为事务代理器,最后在spring容器中使用registerOrEscalateApcAsRequired判断是否存在自动代理器,并决定是否采用InfrastructureAdvisorAutoProxyCreator覆盖已存在的代理器,如果不存在,则创建自动代理器的bean进行注册到容器中,bean类型为AUTO_PROXY_CREATOR_BEAN_NAME即org.springframework.aop.config.internalAutoProxyCreator
。
public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));//调用内部事务自动代理器
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
registerComponentIfNecessary(beanDefinition, parserContext);
}
// InfrastructureAdvisorAutoProxyCreator 自动代理器来实现事务
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 检测AUTO_PROXY_CREATOR_BEAN_NAME 自动代理器bean是否已被注册
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
// 获取自动代理器BeanDefinition
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
// 判断beanName是否一致
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
// 优先级比较,谁的优先级大就使用谁作为自动代理器的class
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 此处代码逻辑是在容器不存在自动代理器时创建自动代理器并使用InfrastructureAdvisorAutoProxyCreator作为其bean的实现类
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;
}
2.1 InfrastructureAdvisorAutoProxyCreator自动代理器
2.1.1 InfrastructureAdvisorAutoProxyCreator层级示意图
InfrastructureAdvisorAutoProxyCreator间接继承了AbstractAutoProxyCreator,AbstractAutoProxyCreator直接实现了SmartInstantiationAwareBeanPostProcessor接口,间接实现了InstantiationAwareBeanPostProcessor接口和BeanPostProcessor接口,那么Spring中的bean在初始化后会调用初始化后方法postProcessAfterInitialization,该方法在父类AbstractAutoProxyCreator中实现。
AbstractAutoProxyCreator->postProcessAfterInitialization初始化后方法逻辑:
- 从缓存中获取bean进行匹配初始化后得到的bean是否一致(循环依赖时导致不一致),不一致则要深入的判断是否需要创建代理bean;
- 深入bean标记、属性过滤、基础设置类如beanFactory类型的bean等条件下不需要创建代理,其他条件则创建代理,先获取增强器,然后根据增强器创建代理bean。
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 获取bean的缓存key,根据class和beanName推测出key
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 判断是否因为避免循环依赖而需要创建的代理,如果需要则创建并封装bean
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey);//封装bean
}
}
return bean;
}
// 经过属性配置、处理标记、基础设置类控制验证后,如果符合条件则直接返回bean,否则创建代理bean返回
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 该beanName、cacheKey、bean是否已经被标记为处理过,如果处理过则直接返回原bean
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 是否是基础设施类或配置忽略,如果是则忽略
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 根据指定bean获取对应的增强器,下面详细分析
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 根据增强器去创建代理bean
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;
}
2.1.2 获取增强器getAdvicesAndAdvisorsForBean
基于wrapIfNecessary中创建代理bean的前提:先获取增强器即getAdvicesAndAdvisorsForBean方法由AbstractAdvisorAutoProxyCreator类负责实现,核心逻辑如下:
- (1)获取增强器即findCandidateAdvisors方法;
- (2)匹配bean与增强器即findAdvisorsThatCanApply;
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//高度封装具体细节,交由findEligibleAdvisors来实现获取和匹配工作
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
2.1.2.1 获取增强器findCandidateAdvisors
先来看一下TransactionAttributeSourceAdvisor层级图,在注册三个bean时,其中有一个bean类型为TransactionAttributeSourceAdvisor,的确是实现了Advisor接口,如下:
findCandidateAdvisors获取增强器代码逻辑:
- (1)从缓存或spring容器中获取实现了Advisor接口的所有增强器bean;
- (2)遍历所有增强器,满足isEligibleBean方法(重写时可能改变Boolean值)设置和isCurrentlyInCreation验证(是否正在创建中)的存储在advisors中作为获取增强器的结果;
protected List<Advisor> findCandidateAdvisors() {
// 验证advisorRetrievalHelper强制有值
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
// 从缓存中直接获取增强器
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// 从Spring容器中获取增强器Advisor
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
// 缓存该值
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// 遍历容器中实现了Advisor接口的所有bean,在事务启动标签annotation-driven中时曾注入过三个bean,如TransactionAttributeSourceAdvisor
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
} else {
try {
// 获取实现了Advisor接口的bean
advisors.add(this.beanFactory.getBean(name, Advisor.class));
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
2.1.2.2 匹配增强器findAdvisorsThatCanApply
整体匹配逻辑:
- (1)先后使用ThreadLocal存储线程变量即currentProxiedBeanName变量存储beanName;
- (2)委托于抽象类AopUtils负责匹配增强器,其中先处理引介增强和普通增强,最后使用三个重载方法canApply分别对应不同场景来匹配,实际上就是为了匹配TransactionAttributeSourceAdvisor增强器;
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
// 设置当前匹配的beanName,currentProxiedBeanName变量存储,类型为ThreadLocal
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
// 清空currentProxiedBeanName变量值
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
// 委托于抽象类AopUtils负责匹配增强器
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
// 先处理引介增强和重载canApply
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) {
return canApply(advisor, targetClass, false);
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
} else if (advisor instanceof PointcutAdvisor) { // TransactionAttributeSourceAdvisor 实现了PointcutAdvisor接口,满足此条件
PointcutAdvisor pca = (PointcutAdvisor) advisor;
// pca.getPointcut() 方法返回的是TransactionAttributeSource的实例
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
} else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
// 该方法尤为重要,前面两个重载方法,当事务TransactionAttributeSourceAdvisor增强器被匹配到时,会调用canApply三参数方法去匹配目标类和类中的所有方法
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;
}
// 获取的是TransactionAttributeSourcePointcut类型的对象,该对象是TransactionAttributeSourceAdvisor类的内部成员变量即pointcut成员变量
MethodMatcher methodMatcher = pc.getMethodMatcher();
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;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
// 获取该类的所有接口
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
// 遍历所有类和方法匹配
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// matches 方法匹配,涉及到事务标签提取,下面第三点中详细分析
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
2.2.2.3 事务标签提取
在findAdvisorsThatCanApply匹配增强器中提到matches方法,该matches是由TransactionAttributeSourcePointcut实例对象调用,tas.getTransactionAttribute(method, targetClass) != null
此代码为BeanFactoryTransactionAttributeSourceAdvisor内部成员变量pointcut调用TransactionAttributeSourcePointcut类中的方法,主要核心逻辑和代码逻辑如下:
提取事务标签逻辑:
- 获取spring初始化加载的TransactionAttributeSource类型的bean即对象tas,然后紧接着是获取事务声明getTransactionAttribute;
- 先从缓存getCacheKey中获取事务声明;
- 缓存中没有则提取事务声明,分为实现类中方法事务声明、实现类级别事务声明、接口中方法事务声明和接口级别事务声明四种类型,满足任意一种即可,优先级为上述顺序;
说明:获取事务时方法必须为公共修饰符类型,否则事务失效。
事务逻辑提取代码:
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();// 返回的是TransactionAttributeSource对象
// getTransactionAttribute方法为BeanFactoryTransactionAttributeSourceAdvisor内部成员变量pointcut调用TransactionAttributeSourcePointcut类中的方法
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
// TransactionAttributeSourcePointcut 中的获取事务属性方法
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}
// 第一步从缓存中获取
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 {
// 第二步缓存中不存在,则开始提取实现类方法、实现类、接口中的方法和接口中去获取事务声明
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
// 缓存事务提取结果
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
} else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
/**
* 提取事务声明步骤:
* (1)首先必须是公共方法
* (2)然后去实现类中的方法中获取事务声明
* (3)实现类级别获取事务声明
* (4)接口中的方法获取事务声明
* (5)接口类级别中获取事务声明
*/
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// 非公共方法则事务失效
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// 获取实现类中的方法,即method对应的实现方法specificMethod
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 第一步:获取方法声明的事务
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}
// 第二步:获取实现类中的事务声明
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
// 最后一步: 实现类中的方法和类中都没有事务的声明,则去接口中获取事务声明
if (specificMethod != method) {
// 查找接口中的方法中的事务声明
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// 接口中类声明是否含有事务声明
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
2.1.2.4 解析事务标签(核心)
经过前面定义的事务逻辑提取框架定义的事务四个步骤:即实现类方法、实现类、接口方法、接口级别中比较核心的是如何解析事务标签,分别委托给AnnotationTransactionAttributeSource类和SpringTransactionAnnotationParser类去完成事务注解、事务的所有属性提取工作;
主要逻辑:
- AnnotationTransactionAttributeSource类负责遍历annotationParsers解析器,去调用SpringTransactionAnnotationParser中解析事务标签中的属性;
- SpringTransactionAnnotationParser类负责提取事务注解Transactional和事务的所有属性提取,最后封装为TransactionAttribute对象返回(实际为RuleBasedTransactionAttribute类型);
提取逻辑:
// AnnotationTransactionAttributeSource类负责寻找事务标签属性
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
// 查找细节委托给determineTransactionAttribute方法
return determineTransactionAttribute(clazz);
}
// 根据element去解析TransactionAttribute事务属性
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
// SpringTransactionAnnotationParser类中的解析方法parseTransactionAnnotation,真正意义上的解析事务属性
TransactionAttribute attr = parser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
/**
* SpringTransactionAnnotationParser类中的解析方法parseTransactionAnnotation
* (1)获取指定element级别中Transactional注解即事务声明;
* (2)对获取到事务注解的AnnotationAttributes对象进行事务属性提取如propagation、isolation、timeout、readOnly、rollbackFor等
*/
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
element, Transactional.class, false, false);
if (attributes != null) {
return parseTransactionAnnotation(attributes);
} else {
return null;
}
}
// 根据Trasactional标签或注解去解析事务中的属性propagation、isolation、readOnly、rollbackForClassName等
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
Propagation propagation = attributes.getEnum("propagation");// 解析 propagation
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");// 解析 isolation
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());// 解析 timeout
rbta.setReadOnly(attributes.getBoolean("readOnly"));// 解析 readOnly
rbta.setQualifier(attributes.getString("value"));// 解析 value
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));// 解析 rollbackFor
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule));// 解析 rollbackForClassName
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));// 解析 noRollbackFor
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule));// 解析 noRollbackForClassName
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
至此,事务初始化工作基本完毕,但是还是值得一提的是,BeanFactoryTransactionAttributeSourceAdvisor 是 Advisor 的实现类,必须遵守 Advisor 的执行方法,当代理被调用时会调用这个类的增强犯法即bean的Advisor,因事务标签在解析时注册了三个bean,其中有一个 bean 为 TransactionInterceptor 类型的bean注入到了 BeanFactoryTransactionAttributeSourceAdvisor 中,即在调用事务增强器增强的代理类时会先执行 TransactionInterceptor 中的增强方法即 invoke 方法,该方法中完成了这个事务的逻辑。
2.1.3 事务增强器(事务实现原理)
TransactionInterceptor 拦截器作为实现事务的核心逻辑,相对来说是比较复杂的,TransactionInterceptor 是实现了 MethodInterceptor 拦截器接口,那么入口就是 invoke 方法,其主要包含spring两种事务支持方式:声明式事务和编程式事务。
- 获取事务属性;
- 加载配置中的TransactionManager;
- 声明式和编程式事务是不同逻辑处理;
- (1)声明式事务时需要获取事务属性的,编程式事务不需要获取事务属性;
- (2)TransactionManager在不同事务方式时处理不同,编程式事务使用CallbackPreferringPlatformTransactionManager作为回调接口类,其实现了PlatformTransactionManager该接口类,内部使用lamda接口方式执行回调方法;
- 在执行目标方法(拦截链proceedWithInvocation)前先调用createTransactionIfNecessary或prepareTransactionInfo先获取事务并设置事务信息如transactionManager、transactionAttribute、joinpointIdentification、transactionStatus和oldTransactionInfo等;
- 执行目标方法即
invocation.proceedWithInvocation();
- 执行过程中,若发生异常则进行回滚
completeTransactionAfterThrowing(txInfo, ex);
目前spring只支持RuntimeException和Error异常回滚; - 清除一些事务性的辅助信息即
cleanupTransactionInfo(txInfo);
- 提交事务即
commitTransactionAfterReturning(txInfo);
public Object invoke(MethodInvocation invocation) throws Throwable {
// 获取目标类,该值可能为空,不为空时则将TransactionAttributeSource传递给目标类,也可能是来自接口中的方法
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// 将方法、目标类等都以适配器模式进行传递实现
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// 获取TransactionAttributeSource事务对象
TransactionAttributeSource tas = getTransactionAttributeSource();
// 获取事务属性
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
// 获取 beanFactory 中的 transactionManager
final TransactionManager tm = determineTransactionManager(txAttr);
// 事务管理器适配器校验
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
ReactiveTransactionSupport txSupport = this.transactionSupportCache.computeIfAbsent(method, key -> {
if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && KotlinDelegate.isSuspend(method)) {
throw new TransactionUsageException(
"Unsupported annotated transaction on suspending function detected: " + method + ". Use TransactionalOperator.transactional extensions instead.");
}
ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
if (adapter == null) {
throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
}
return new ReactiveTransactionSupport(adapter);
});
return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager) tm);
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
// 构建一个方法的唯一标识即全路径方法名
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// 处理声明式事务
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// 创建事务TransactionInfo对象
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// 执行被增强的方法,该方法是环绕通知类型
retVal = invocation.proceedWithInvocation();
} catch (Throwable ex) {
// 执行抛出异常的方法
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
// 清除一些辅助信息
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();
//
try {
result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
// txInfo事务信息对象获取
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
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;
}
}
2.1.3.1 创建事务createTransactionIfNecessary
概括一下主要事件:
- (1)扩展事务属性:使用DelegatingTransactionAttribute来封装TransactionAttribute实例,txAttr.getName()默认在接口中是返回null,所以此处为DelegatingTransactionAttribute封装,提供更多的扩展功能;
- (2)获取事务:通过PlatformTransactionManager来获取事务即
tm.getTransaction(txAttr);
参照Spring事务原理番外篇 - (3)封装事务信息:封装TransactionInfo事务信息实例即
prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
说明:其中txInfo.bindToThread();
有使用到ThreadLocal来保存事务线程信息。
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// 判断事务属性是否有设置名称,没有则使用DelegatingTransactionAttribute生成TransactionAttribute对象txAttr
if (txAttr != null && txAttr.getName() == null) {
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
// 获取事务TransactionStatus(核心,单独细讲)
status = tm.getTransaction(txAttr);
} else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
// 根据上述txAttr、status、joinpointIdentification封装TransactionInfo
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}
//封装TransactionInfo
protected TransactionInfo prepareTransactionInfo(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, String joinpointIdentification,
@Nullable TransactionStatus status) {
TransactionInfo txInfo = new TransactionInfo(tm, txAttr, joinpointIdentification);// 封装事务TransactionInfo
if (txAttr != null) {
if (logger.isTraceEnabled()) {
logger.trace("Getting transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.newTransactionStatus(status);
} else {
if (logger.isTraceEnabled()) {
logger.trace("No need to create transaction for [" + joinpointIdentification +
"]: This method is not transactional.");
}
}
// 调用线程私有绑定 ThreadLocal
txInfo.bindToThread();
return txInfo;
}
private static final ThreadLocal<TransactionInfo> transactionInfoHolder = new NamedThreadLocal<>("Current aspect-driven transaction");
private void bindToThread() {
// 线程绑定ThreadLocal
this.oldTransactionInfo = transactionInfoHolder.get();
transactionInfoHolder.set(this);
}
2.1.3.2 回滚处理——completeTransactionAfterThrowing
2.1.3.2.1 回滚条件
- (1)对满足默认回滚条件的异常类型RuntimeException或Error进行回滚;(可自行扩展回滚条件如重写rollbackOn方法)
- (2)对不满足回滚条件的义无反顾的提交事务;
说明:Spring默认回滚的异常条件为:RuntimeException或Error类型的异常;
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
// 对存在的事务进行处理
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
// 只处理默认的RuntimeException或Error类型的异常进行回滚
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
// 根据TransactionStatus信息进行回滚
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
} catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
} else {
// 不满足上述的回滚条件则仍然提交
try {
// 出现异常依然提交事务
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
} catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
} catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
// 默认的回滚事务类型条件
public boolean rollbackOn(Throwable ex) {
return (ex instanceof RuntimeException || ex instanceof Error);
}
2.1.3.2.2 回滚处理——rollback
- (1)调用自定义触发器,包含回滚前——
triggerBeforeCompletion()
、回滚后——triggerAfterCompletion()
调用,触发器也会对正常回滚、回滚过程中出现的异常进一步处理,而注册触发器是通过 TransactionSynchronizationManager 类中静态方法直接注册public static void registerSynchronization(TransactionSynchronization synchronization) throws IllegalStateException; - (2)回滚操作——
doRollback(status);
分为三种回滚,嵌入式事务回滚
、单独事务回滚
、JTA事务回滚标记;
嵌入式事务回滚: 对于保存点事务的回滚主要是调用JDBC连接中的JdbcTransactionObjectSupport#rollbackToSavepoint方法回滚;
单独事务回滚: 对于没有保存点的事务,直接回滚,Spring也是使用JDBC数据库连接中的DataSourceTransactionManager#doRollback方法回滚;
JTA事务回滚: 当前存在事务,不属于上述嵌入式和单独事务时,则只做回滚标记,只能等到提交时作统一回滚;
public final void rollback(TransactionStatus status) throws TransactionException {
// 对于已完成的事务,此时回滚会导致报错
if (status.isCompleted()) {
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// Spring 将回滚逻辑单独封装
processRollback(defStatus, false);
}
// 回滚逻辑单独封装
private void processRollback(DefaultTransactionStatus status, boolean unexpected) {
try {
boolean unexpectedRollback = unexpected;
try {
// 激活TransactionSynchronization中的triggerBeforeCompletion方法
triggerBeforeCompletion(status);
// 对于有保存点,将事务回滚到保存点
if (status.hasSavepoint()) {
if (status.isDebug()) {
logger.debug("Rolling back transaction to savepoint");
}
status.rollbackToHeldSavepoint();
} else if (status.isNewTransaction()) {// 如果是新事务,则直接将该事务回滚
if (status.isDebug()) {
logger.debug("Initiating transaction rollback");
}
doRollback(status);// 回滚当前事务
} else {
// 当前事务不是单独的事务,只能标记,等到事务链执行完毕后统一进行回滚
if (status.hasTransaction()) {
if (status.isLocalRollbackOnly() || isGlobalRollbackOnParticipationFailure()) {
if (status.isDebug()) {
logger.debug("Participating transaction failed - marking existing transaction as rollback-only");
}
// 打标记
doSetRollbackOnly(status);
} else {
if (status.isDebug()) {
logger.debug("Participating transaction failed - letting transaction originator decide on rollback");
}
}
} else {
logger.debug("Should roll back transaction but cannot - no transaction available");
}
// Unexpected rollback only matters here if we're asked to fail early
if (!isFailEarlyOnGlobalRollbackOnly()) {
unexpectedRollback = false;
}
}
} catch (RuntimeException | Error ex) {
triggerAfterCompletion(status, TransactionSynchronization.STATUS_UNKNOWN);
throw ex;
}
// 激活TransactionSynchronization中的triggerAfterCompletion方法
triggerAfterCompletion(status, TransactionSynchronization.STATUS_ROLLED_BACK);
// Raise UnexpectedRollbackException if we had a global rollback-only marker
if (unexpectedRollback) {
throw new UnexpectedRollbackException(
"Transaction rolled back because it has been marked as rollback-only");
}
} finally {
// 清空记录的资源并将其挂起的资源进行恢复
cleanupAfterCompletion(status);
}
}
2.1.3.3 回滚后清除——cleanupAfterCompletion
当回滚操作执行完毕后,无论回滚成功、还是回滚失败,都需要在执行完毕后进行收尾工作,如下:
- (1)设置事务完成状态,避免重复调用;
- (2)如果当前事务时新的同步状态,需要将绑定到当前线程的事务信息清除;
- (3)如果是新事务则需要释放资源;(Spring事务原理番外篇)
- (4)如果执行该事务前有将其他事务挂起,则该事务结束后,需要唤醒被挂起的事务;
private void cleanupAfterCompletion(DefaultTransactionStatus status) {
status.setCompleted();// 设置完成状态 true
// 同步事务清除
if (status.isNewSynchronization()) {
/** 清除同步保存的设置
* synchronizations.remove();
* currentTransactionName.remove();
* currentTransactionReadOnly.remove();
* currentTransactionIsolationLevel.remove();
* actualTransactionActive.remove();
*/
TransactionSynchronizationManager.clear();
}
// 单独事务清除
if (status.isNewTransaction()) {
/**
* (1)将当前线程中的数据库连接解除绑定;
* (2)释放数据库连接、恢复数据库连接自动提交属性、重置数据库连接;
* (3)如果当前事务是单独新创建,则需要立即释放数据库连接;
*/
doCleanupAfterCompletion(status.getTransaction());
}
// 判断是否有被挂起的事务
if (status.getSuspendedResources() != null) {
if (status.isDebug()) {
logger.debug("Resuming suspended transaction after completion of inner transaction");
}
Object transaction = (status.hasTransaction() ? status.getTransaction() : null);
// 唤醒挂起的事务
resume(transaction, (SuspendedResourcesHolder) status.getSuspendedResources());
}
}
protected final void resume(@Nullable Object transaction, @Nullable SuspendedResourcesHolder resourcesHolder)
throws TransactionException {
if (resourcesHolder != null) {
Object suspendedResources = resourcesHolder.suspendedResources;
if (suspendedResources != null) {
doResume(transaction, suspendedResources);// 唤醒
}
// 设置挂起的事务属性
List<TransactionSynchronization> suspendedSynchronizations = resourcesHolder.suspendedSynchronizations;
if (suspendedSynchronizations != null) {
TransactionSynchronizationManager.setActualTransactionActive(resourcesHolder.wasActive);
TransactionSynchronizationManager.setCurrentTransactionIsolationLevel(resourcesHolder.isolationLevel);
TransactionSynchronizationManager.setCurrentTransactionReadOnly(resourcesHolder.readOnly);
TransactionSynchronizationManager.setCurrentTransactionName(resourcesHolder.name);
doResumeSynchronization(suspendedSynchronizations);
}
}
}
2.1.3.3 事务提交——commitTransactionAfterReturning
在事务提交前会进行判断,也就是嵌入式事务且无法设置保存点时,如果发生回滚,前面提到过三种回滚方式,如JTA方式是仅仅给了一个回滚标记,此时在这里将会发挥作用,当在commit提交时会进行判断该标记,若存在,则进行统一回滚;否则正常提交;
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
// 判断事务存在时提交才有意义
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
// 将事务提交操作封装,由AbstractPlatformTransactionManager类来实现
public final void commit(TransactionStatus status) throws TransactionException {
if (status.isCompleted()) {// 判断事务是否已完成,若完成还提交,则报异常
throw new IllegalTransactionStateException(
"Transaction is already completed - do not call commit or rollback more than once per transaction");
}
DefaultTransactionStatus defStatus = (DefaultTransactionStatus) status;
// 是否存在统一回滚标志
if (defStatus.isLocalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Transactional code has requested rollback");
}
// 直接回滚,false代表回滚标记
processRollback(defStatus, false);
return;
}
if (!shouldCommitOnGlobalRollbackOnly() && defStatus.isGlobalRollbackOnly()) {
if (defStatus.isDebug()) {
logger.debug("Global transaction is marked as rollback-only but transactional code requested commit");
}
// 事务回滚,true代表仅回滚
processRollback(defStatus, true);
return;
}
// 事务提交,由事务原理番外篇细讲
processCommit(defStatus);
}
因篇幅原因,关于事务提交processCommit(defStatus);
具体实现请查阅Spring事务原理番外篇