事务解析原理

事务的解析与执行是依赖AOP实现的,Spring中开启事务是通过@EnableTransactionManagement注解来完成的,在该注解上通过@Import为容器导入了一个组件TransactionManagementConfigurationSelector,该组件是一个ImportSelector其为容器注册一个为AutoProxyRegistrarImportBeanDefinitionRegistrar开启AOP代理,以及一个事务代理的配置类ProxyTransactionManagementConfiguration导入关于事务的切面信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
// 在容器中加载Bean定义时回调selectImports方法,该方法返回值需要导入类的全类名路径,然后这个类会被加载到容器中
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) { // 为容器中导入AutoProxyRegistrar、ProxyTransactionManagementConfiguration
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ: // 绝大部分情况下,不会使用AspectJ的静态代理的
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
private String determineTransactionAspectClass() {
return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}
}

AdviceModeImportSelector目前所知有AsyncConfigurationSelectorTransactionManagementConfigurationSelectorCachingConfigurationSelector三个子类。明显缓存体系@EnableCaching和异步@EnableAsync模式也是和这个极其类似的。自动代理注册AutoProxyRegistrar的作用是向容器注册一个解析事务的后置处理器InfrastructureAdvisorAutoProxyCreator。首先获取到所有的注解类型,而不是只获取@EnableAspectJAutoProxy注解,因为modeproxyTargetClass等属性会直接影响到代理得方式,而@EnableTransactionManagement@EnableAsync@EnableCaching@EnableAspectJAutoProxy等注解都拥有这些属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annTypes = importingClassMetadata.getAnnotationTypes(); // 获取所有的注解类型
for (String annType : annTypes) {
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
if (candidate == null) {
continue;
}
Object mode = candidate.get("mode"); // 默认PROXY
Object proxyTargetClass = candidate.get("proxyTargetClass"); // 是否强制使用Cglib代理
// 存在mode且存在proxyTargetClass属性,且两个属性的class类型也是对的
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() && Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true; // 标志找到候选注解
if (mode == AdviceMode.PROXY) {
// 注册了internalAutoProxyCreator,但若出现多次,这里不是覆盖而是以第一次的为主
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
}
}

开启AOP代理类似这里通过AopConfigUtilsregisterAutoProxyCreatorIfNecessary真正去注册该后置处理器。最终调用registerOrEscalateApcAsRequired该方法和开启AOP代理时调用的是同一个方法,且向容器中注册的Bean的名称都是同一个internalAutoProxyCreator。这里会根据优先级来确定注册哪个类。AOP的会覆盖事务的, 因为AOP优先级更大。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public abstract class AopConfigUtils {
private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
static {
APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
}
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAutoProxyCreatorIfNecessary(registry, null);
}
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");
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;
}
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;
}
private static int findPriorityForClass(Class<?> clazz) {
return APC_PRIORITY_LIST.indexOf(clazz);
}

private static int findPriorityForClass(@Nullable String className) {
for (int i = 0; i < APC_PRIORITY_LIST.size(); i++) {
Class<?> clazz = APC_PRIORITY_LIST.get(i);
if (clazz.getName().equals(className)) {
return i;
}
}
throw new IllegalArgumentException("Class name [" + className + "] is not a known auto-proxy creator class");
}
}

同时开启AOP事务根据优先级最终还是加载的解析和创建AOP代理的后置处理器AnnotationAwareAspectJAutoProxyCreator,且其与InfrastructureAdvisorAutoProxyCreator都是上层接口都是一样的。这里重写了isEligibleAdvisorBean方法。

1
2
3
4
5
6
7
8
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Override
protected boolean isEligibleAdvisorBean(String beanName) {
// 容器中包含了这个bean定义,并且bean定义角色为BeanDefinition.ROLE_INFRASTRUCTURE
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
}
}

ProxyTransactionManagementConfiguration是一个@Configuration事务配置类,其主要作用是配置一个处理事务的Advisor。配置的事务拦截器是一个MethodInterceptor,也可以自定义一个同名的TransactionInterceptor来覆盖此Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource());
advisor.setAdvice(transactionInterceptor());
if (this.enableTx != null) {
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
}
return advisor; // 导入了关于事务的切面信息
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource(); // 事务属性源对象,用于获取事务属性对象
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() { // 用户拦截事务方法执行的
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}

AnnotationTransactionAttributeSource基于注解驱动的事务管理的事务属性源,其作用是解析@Transactional注解,将其解析成TransactionAttribute后后续调用,也可如下自定义事务属性源,通过名称匹配的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Bean
public TransactionAttributeSource transactionAttributeSource() {
Map<String, TransactionAttribute> txMap = new HashMap<>();
// required事务适用于增删改场景
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(RuntimeException.class)));
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
txMap.put("add*", requiredTx);
txMap.put("save*", requiredTx);
txMap.put("insert*", requiredTx);
txMap.put("update*", requiredTx);
txMap.put("delete*", requiredTx);
// 查询 使用只读事务
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
txMap.put("get*", readOnlyTx);
txMap.put("query*", readOnlyTx);

NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
source.setNameMap(txMap);
return source;
}

BeanFactoryTransactionAttributeSourceAdvisor会在切面解析时第一个被实例化的Bean调用时被BeanFactoryAdvisorRetrievalHelperfindAdvisorBeans中被解析出来并将其名称放入cachedAdvisorBeanNames缓存中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;
// 事务属性源切点
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource; // 可手动设置一个事务属性源
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
}

事务切面解析时和AOP的切面相同的逻辑,同样调用的是canApply方法经过了初筛精筛,事务这初筛一般是通过的。初筛时调用TransactionAttributeSourceClassFiltermatches方法,精筛最终是通过MethodMatchermatches方法,实际调用TransactionAttributeSourcePointcutmatches方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches(Method method, @Nullable Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
// 获取我们@EnableTransactionManagement注解为容器中导入的ProxyTransactionManagementConfiguration配置类中的TransactionAttributeSource对象
TransactionAttributeSource tas = getTransactionAttributeSource();
// 通过getTransactionAttribute看是否有@Transactional注解
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}
@Nullable
protected abstract TransactionAttributeSource getTransactionAttributeSource();
private class TransactionAttributeSourceClassFilter implements ClassFilter {
@Override
public boolean matches(Class<?> clazz) {
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
PlatformTransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.isCandidateClass(clazz));
}
}
}

最终调用AnnotationTransactionAttributeSource的超类AbstractFallbackTransactionAttributeSource中的getTransactionAttribute方法。若method所在的类是Object则直接返回空,否则先从缓存中获取,若缓存为空说明没有被解析过,则通过computeTransactionAttribute去解析,无论是否解析到事务属性都将其放入缓存中。还会把方法描述设置到事务属性descriptor上去,调用的时候会从事务属性中获取。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource {
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null; // 判断method所在的class是否为Object类型
}
Object cacheKey = getCacheKey(method, targetClass);// 构建缓存key
TransactionAttribute cached = this.attributeCache.get(cacheKey);// 先去缓存中获取
if (cached != null) {// 缓存中不为空
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);
}
this.attributeCache.put(cacheKey, txAttr);//加入到缓存
}
return txAttr;
}
}
}

首先去目标类的当前方法上去找事务注解,若找到直接解析返回,若找不到再去目标类上去找事务注解,若找不到,再判断若具体方法不是当前的方法说明当前方法是接口方法,再去实现类的接口上的方法去找事务注解,最后再去实现类的接口上去找事务注解。

getMostSpecificMethod是得到具体的方法,若method是接口方法将从targetClass得到实现类的方法,故无论传的是接口还是实现,都会先解析实现类。可从该代码逻辑看出,@Transactional注解既可以用在方法上还可以用在上甚至是接口方法接口上,但若这些地方都有该注解,则方法上的该注解会覆盖类上的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource {
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null; // 判断事务方法上的修饰符是不是public的
}
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// 去目标class的方法上去找事务注解
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;
}
}

这里的findTransactionAttribute调用是AnnotationTransactionAttributeSource的方法,最终会调用SpringTransactionAnnotationParserparseTransactionAnnotation。初筛的matches方法实际调用的是该类的isCandidateClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {
private final Set<TransactionAnnotationParser> annotationParsers;
public AnnotationTransactionAttributeSource() {
this(true);
}
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) { // 是否支持 jta和 ejb的事务解析
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
} else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());
}
}
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
return determineTransactionAttribute(clazz);
}
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser annotationParser : this.annotationParsers) { // 获取注解解析器
// 通过注解解析器去解析方法或类上的注解
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
if (attr != null) {
return attr;
}
}
return null;
}
public boolean isCandidateClass(Class<?> targetClass) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
if (parser.isCandidateClass(targetClass)) {
return true;
}
}
return false;
}
}

若在目标元素上找到@Transactional注解,则通过parseTransactionAnnotation方法对该注解属性进行解析。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
public boolean isCandidateClass(Class<?> targetClass) {
return AnnotationUtils.isCandidateClass(targetClass, Transactional.class);
}
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
// 从element对象中获取@Transactional注解,然后把注解属性封装到了AnnotationAttributes
AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(element, Transactional.class, false, false);
if (attributes != null) {// 解析出真正的事务属性对象
return parseTransactionAnnotation(attributes);
} else {
return null;
}
}
public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
}
protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute(); // 创建一个基础规则的事务属性对象
Propagation propagation = attributes.getEnum("propagation"); // 解析@Transactionl上的传播行为
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation"); // 解析@Transactionl上的隔离级别
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue()); // 解析@Transactionl上的事务超时事件
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value")); // 解析@Transactionl上的事务管理器的名称
List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule)); // 针对哪种异常回滚
}
for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
rollbackRules.add(new RollbackRuleAttribute(rbRule)); // 对哪种异常进行回滚
}
for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule)); // 对哪种异常不回滚
}
for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
rollbackRules.add(new NoRollbackRuleAttribute(rbRule)); // 对哪种类型不回滚
}
rbta.setRollbackRules(rollbackRules);
return rbta;
}
}