spring事务管理源码分析(一)配置和事务增强代理的生成流程

在本篇文章中,将会介绍如何在spring中进行事务管理,之后对其内部原理进行分析。主要涉及

  1. @EnableTransactionManagement注解为我们做了什么?
  2. 为什么标注了@Transactional注解的方法就可以具有事务的特性,保持了数据的ACID特性?spring到底是如何具有这样的偷梁换柱之术的?
  3. 中间涉猎到一些spring关于注解配置的解析逻辑分析,这一部分比较通用,并不是spring事务管理模块特有的功能。在往后分析spring其他模块代码的时候可以借鉴

如何在spring应用中使用事务

我们可以在配置类上标记注解@EnableTransactionManagement,这样就可以设置spring应用开启事务管理。 之后我们可以在需要开启事务的方法上标注@Transactional,spring将利用AOP框架,生成代理类,为方法配置事务增强。下面看一个具体的例子

demo

配置类

1
2
3
4
5
6
@Configuration
@EnableTransactionManagement // 我们这一节的重点研究对象
public class MybatisConfig {

// 各种其他配置,如数据源配置、mybatis的SqlSessionFactory等
}

需要事务增强的接口类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 接口类
public interface CountryService {
int createCountry(Country country);

}

// 实现,我们故意让其抛出异常
public class CountryServiceImpl implements CountryService {

// ... 注入countryMapper

@Override
@Transactional
public int createCountry(Country country) {
// 使用mybatis mapper来操作数据库
int result = countryMapper.insert(country);
int i = 1 / 0; // 抛出RuntimeException,事务回滚
return result;
}
}

使用接口

1
2
3
4
5
6
7
8
9
10
11
12
public class ContextTest {

public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MybatisConfig.class);
CountryService countryService = context.getBean(CountryService.class);
Country country = new Country();
country.setCountryName("中国");
country.setCountryCode("CN");
// 由于我们在countryService中,抛出了异常。因此这里的数据将发生回滚,不会写入到数据库中
countryService.createCountry(country);
}
}

demo说明了什么?

从以上的demo,我们可以看出来。利用spring的事务管理框架,我们只需要三个步骤即可:

  1. 通过注解@EnableTransactionManagement,开启spring的事务管理功能
  2. 在接口类的需要事务增强的方法上,标注@Transactional
  3. 在容器中使用增强后的代理类的事务方法,如countryService.createCountry(country)

spring是如何做到的呢?

区区三个步骤,就可以让我们解耦数据访问、事务管理这两个功能模块。神奇的背后,到底隐藏着什么原理呢?

从@EnableTransactionManagement开始探险

EnableTransactionManagement
1
2
3
4
5
6
7
8
9
10
11
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

boolean proxyTargetClass() default false;
AdviceMode mode() default AdviceMode.PROXY;
int order() default Ordered.LOWEST_PRECEDENCE;

}

从注解的代码中,可以看出在其内部通过@Import注解导入了TransactionManagementConfigurationSelector类

TransactionManagementConfigurationSelector
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

/**
* {@inheritDoc}
* @return {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
* {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
}


TransactionManagementConfigurationSelector实现了接口ImportSelector

spring加载配置流程

由于整个解析配置的流程过于复杂,代码量繁多。这里就不一一列出具体代码了。下面提供一个主流程的时序图,有兴趣的看官可以跟着流程图去浏览一下相关源码。

在spring解析配置的过程中,将调用方法AutoProxyRegistrar#registerBeanDefinitions,最终向容器中注册了自动代理生成器InfrastructureAdvisorAutoProxyCreator

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
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
boolean candidateFound = false;
Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
for (String annoType : annoTypes) {
AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
if (candidate == null) {
continue;
}
Object mode = candidate.get("mode");
Object proxyTargetClass = candidate.get("proxyTargetClass");
if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
Boolean.class == proxyTargetClass.getClass()) {
candidateFound = true;
if (mode == AdviceMode.PROXY) {
// 该方法内部将注册一个自动生成代理类(InfrastructureAdvisorAutoProxyCreator)
AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
if ((Boolean) proxyTargetClass) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
return;
}
}
}
}
if (!candidateFound) {
String name = getClass().getSimpleName();
logger.warn(String.format("%s was imported but no annotations were found " +
"having both 'mode' and 'proxyTargetClass' attributes of type " +
"AdviceMode and boolean respectively. This means that auto proxy " +
"creator registration and configuration may not have occurred as " +
"intended, and components may not be proxied as expected. Check to " +
"ensure that %s has been @Import'ed on the same class where these " +
"annotations are declared; otherwise remove the import of %s " +
"altogether.", name, name, name));
}
}

而且,在解析配置的过程中,将处理Import进来的配置类ProxyTransactionManagementConfiguration。
其内部存在三个用@Bean注解标注的方法如下,将向容器注册其各自返回的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
30
31
32
33
34
@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());
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
return advisor;
}

//
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}

// 切面逻辑(Advice)
@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;
}

}

解析配置后的成果
  1. 注册了自动代理生成器InfrastructureAdvisorAutoProxyCreator
  2. 注册了ProxyTransactionManagementConfiguration,其内部会通过@Bean标注的方法,进而注册BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor
spring是如何为我们进行事务增强的

spring通过AOP框架在容器启动时,自动发现需要事务增强的类或方法(即标注了@Transactional的类或方法),为这些方法嵌入事务切面(即BeanFactoryTransactionAttributeSourceAdvisor)生成代理类,之后我们从容器获取到的对应的bean就是进行事务增强后的代理类。大致的步骤包括:

  1. InfrastructureAdvisorAutoProxyCreator作为BeanPostProcessor,在容器启动期间其postProcessAfterInitialization方法被调用,作为创建事务增强代理对象的入口
  2. 之后从beanfactory中获取所有Advisor实现类的实例,使用每一个获取到的Advisor中的Pointcut对当前正在创建的bean进行匹配,在这里Advisor为BeanFactoryTransactionAttributeSourceAdvisor、Pointcut为TransactionAttributeSourcePointcut
  3. 匹配过程中会调用TransactionAttributeSourcePointcut的matches(Method method, Class<?> targetClass)方法来进行匹配判断,判断的工作需要借助AnnotationTransactionAttributeSource#getTransactionAttribute(Method method, Class<?> targetClass)来解析注解@Transactional
  4. 如果匹配成功,则证明需要生成事务增强代理。会返回BeanFactoryTransactionAttributeSourceAdvisor实例,作为切面设置到ProxyFactory中,用于生成代理
  5. 通过ProxyFactory来生成事务增强代理

大致的流程图如下所示

事务增强代理生成过程的源码分析
InfrastructureAdvisorAutoProxyCreator(BeanPostProcessor)
1
2
3
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
// postProcessAfterInitialization接口在其父类中实现
}
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
48
49
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

@Override
public Object postProcessAfterInitialization(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;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (beanName != null && 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;
}

// Create proxy if we have advice.
// 在这个方法内部将调用TransactionAttributeSourcePointcut#match方法进行匹配,如果匹配成功那么会返回BeanFactoryTransactionAttributeSourceAdvisor实例
// 这个方法完成了以下几个工作
// 1. 从beanfactory中获取所有注册到beanfactory中的Advisor,将Advisor进行实例化
// 2. 调用Advisor中的Pointcut的matches方法,进行匹配。匹配成功则返回当前Advisor
// 3. 在事务管理的框架中,匹配细节由TransactionAttributeSourcePointcut#matches方法负责,其内部会调用AnnotationTransactionAttributeSource#getTransactionAttribute方法解析@Transactional注解
// 4. 对于局部事务来说,解析@Transactional的解析将委托给SpringTransactionAnnotationParser
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 在这个方法内部将使用ProxyFactory来生成代理
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;
}

}
BeanFactoryTransactionAttributeSourceAdvisor(Advisor)

这里先看一下BeanFactoryTransactionAttributeSourceAdvisor的类图,大概了解下这个类是在整个事务管理体系中是属于什么角色。

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
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

private TransactionAttributeSource transactionAttributeSource;

// 切面内的Pointcut,用于在生成代理的过程中进行匹配方法
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
@Override
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};


/**
* Set the transaction attribute source which is used to find transaction
* attributes. This should usually be identical to the source reference
* set on the transaction interceptor itself.
* @see TransactionInterceptor#setTransactionAttributeSource
*/
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}

/**
* Set the {@link ClassFilter} to use for this pointcut.
* Default is {@link ClassFilter#TRUE}.
*/
public void setClassFilter(ClassFilter classFilter) {
this.pointcut.setClassFilter(classFilter);
}

@Override
public Pointcut getPointcut() {
return this.pointcut;
}

}

可以看出,这个类间接实现了接口PointcutAdvisor,这是一个切面类(即组合了Pointcut、Advice)。其内部定义的Pointcut为抽象类TransactionAttributeSourcePointcut的匿名实现类。关于AOP的这些概念,可以参考:spring-AOP原理分析一spring-AOP原理分析二,这里不再赘述。

TransactionAttributeSourcePointcut(Pointcut)


这个类间接实现了两个接口:Pointcut、MethodMatcher。在事务管理中作为AOP的pointcut、methodMatcher两个角色。用于匹配方法是否需要进行事务增强

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
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

// 通过AnnotationTransactionAttributeSource来获取
@Override
public boolean matches(Method method, Class<?> targetClass) {
if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
return false;
}
// 获取到的tas为AnnotationTransactionAttributeSource实例,
// 在ProxyTransactionManagementConfiguration中注册而来
TransactionAttributeSource tas = getTransactionAttributeSource();
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof TransactionAttributeSourcePointcut)) {
return false;
}
TransactionAttributeSourcePointcut otherPc = (TransactionAttributeSourcePointcut) other;
return ObjectUtils.nullSafeEquals(getTransactionAttributeSource(), otherPc.getTransactionAttributeSource());
}

@Override
public int hashCode() {
return TransactionAttributeSourcePointcut.class.hashCode();
}

@Override
public String toString() {
return getClass().getName() + ": " + getTransactionAttributeSource();
}


/**
* Obtain the underlying TransactionAttributeSource (may be {@code null}).
* To be implemented by subclasses.
*/
protected abstract TransactionAttributeSource getTransactionAttributeSource();

}

AnnotationTransactionAttributeSource


在TransactionAttributeSourcePointcut#matches(Method method, Class<?> targetClass)方法中,将调用AnnotationTransactionAttributeSource#getTransactionAttribute(Method method, Class<?> targetClass)方法,用于获取TransactionAttribute,即配置到@Transactional的属性值。实际的获取动作代理给了父类AbstractFallbackTransactionAttributeSource

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
implements Serializable {

// ... 省略code

}

public abstract class AbstractFallbackTransactionAttributeSource implements TransactionAttributeSource {

@Override
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
if (method.getDeclaringClass() == Object.class) {
return null;
}

// First, see if we have a cached value.
Object cacheKey = getCacheKey(method, targetClass);
Object 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 (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;
}
}

// 解析@Transaction注解的属性值
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
// Don't allow no-public methods as required.
// 1. 只有public方法可以切入事务管理
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}

// Ignore CGLIB subclasses - introspect the actual user class.
Class<?> userClass = ClassUtils.getUserClass(targetClass);
// 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 = ClassUtils.getMostSpecificMethod(method, userClass);
// If we are dealing with method with generic parameters, find the original method.
specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

// First try is the method in the target class.
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
if (txAttr != null) {
return txAttr;
}

// Second try is the transaction attribute on the target class.
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}

if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}

return null;
}

@Override
protected TransactionAttribute findTransactionAttribute(Method method) {
return determineTransactionAttribute(method);
}

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
if (ae.getAnnotations().length > 0) {
// TransactionAnnotationParser的实现类有Ejb3TransactionAnnotationParser、JtaTransactionAnnotationParser、SpringTransactionAnnotationParser
// 对于局部失误,我们使用SpringTransactionAnnotationParser来进行解析
for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
if (attr != null) {
return attr;
}
}
}
return null;
}

}

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

@Override
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
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");
rbta.setPropagationBehavior(propagation.value());
Isolation isolation = attributes.getEnum("isolation");
rbta.setIsolationLevel(isolation.value());
rbta.setTimeout(attributes.getNumber("timeout").intValue());
rbta.setReadOnly(attributes.getBoolean("readOnly"));
rbta.setQualifier(attributes.getString("value"));
ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();
Class<?>[] rbf = attributes.getClassArray("rollbackFor");
for (Class<?> rbRule : rbf) {
RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
String[] rbfc = attributes.getStringArray("rollbackForClassName");
for (String rbRule : rbfc) {
RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
for (Class<?> rbRule : nrbf) {
NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
for (String rbRule : nrbfc) {
NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
rollBackRules.add(rule);
}
rbta.getRollbackRules().addAll(rollBackRules);
return rbta;
}

@Override
public boolean equals(Object other) {
return (this == other || other instanceof SpringTransactionAnnotationParser);
}

@Override
public int hashCode() {
return SpringTransactionAnnotationParser.class.hashCode();
}

}

总结

以上我们从一个demo入手,了解了如何使用spring来管理事务;之后我们从配置的注解@EnableTransactionManagement切入到spring事务框架的内部原理。期间涉及了几个主要的类:

  1. AutoProxyRegistrar其主要职责是注册InfrastructureAdvisorAutoProxyCreator
    1.1 InfrastructureAdvisorAutoProxyCreator,负责在容器启动期间利用配置信息生成事务增强的代理类对象
  2. ProxyTransactionManagementConfiguration其主要职责是注册AnnotationTransactionAttributeSource、TransactionInterceptor、BeanFactoryTransactionAttributeSourceAdvisor
    2.1 AnnotationTransactionAttributeSource负责解析@Transactional注解
    2.2 BeanFactoryTransactionAttributeSourceAdvisor作为切面,组合了Pointcut和Advice提供了事务管理的功能
  3. TransactionAttributeSourcePointcut作为Pointcut,负责匹配方法
  4. TransactionInterceptor作为Advice,事务管理的逻辑都在这个类中进行实现。

悬念

鉴于篇幅过长了,O(≧口≦)O。。。下一节我们再对事务管理的逻辑进行剖析,即对TransactionInterceptor进行分析