Spring事务源码分析

关于事务的具体概念和使用方式,Spring事务管理有详细介绍

基于注解的事务管理

1
2
3
4
5
6
7
8
9
10
11
12
<!-- 数据源配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="#{jdbc['jdbc.driverClassName']}"/>
</bean>
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!-- 开启注解方式配置事物 -->
<tx:annotation-driven transaction-manager="transactionManager"/>

Spring事务调用过程

Spring事务使用AOP代理后的方法调用执行流程,如图所示:

2

从图中可以看出,调用事务时首先调用的是AOP代理对象而不是目标对象,首先执行事务切面,事务切面内部通过TransactionInterceptor环绕增强进行事务的增强。即进入目标方法之前开启事务,退出目标方法时提交/回滚事务。

源码分析

假设配置两个以上的<tx:annotation-driven/>标签:

1
2
3
4
5
6
7
8
9
10
<tx:annotation-driven transaction-manager="transactionManager1"/>
<bean id="transactionManager1"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource1"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager2"/>
<bean id="transactionManager2"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource2"/>
</bean>

结果只有第一个<tx:annotation-driven/>会生效,也就是使用@Transactional注解时不指定事务管理器,默认使用的事务管理器是transactionManager1。如果要使用多个事务管理器,需要在使用@Transactional时指定具体的TransactionManager

<tx:annotation-driven/>分析

这个标签是由TxNamespaceHandler解析的,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class TxNamespaceHandler extends NamespaceHandlerSupport {
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
public void init() {
// advice标签解析
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
// annotation-driven标签解析
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
// jta-transaction-manager分布式事务标签解析
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
}

这里关注AnnotationDrivenBeanDefinitionParser解析器,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
// 提供对aspectj方式进行事务切入的支持
registerTransactionAspect(element, parserContext);
}
else {
// mode="proxy"
// 默认采用aop代理方式
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
}

AopAutoProxyConfigurer作为AnnotationDrivenBeanDefinitionParser静态内部类,关键代码如下:

重点代码被红框标记,最外层的if判断保证<tx:annotation-driven/>标签只能被解析一次,所以只有第一次被解析的标签会生效。分别注册了三个BeanDefinition,分别为AnnotationTransactionAttributeSourceTransactionInterceptorBeanFactoryTransactionAttributeSourceAdvisor,并将前两个BeanDefinition添加到第三个BeanDefinition的属性当中,这三个bean支撑了整个事务功能

下面关注事务管理怎么注册的:

1
2
3
4
5
6
7
8
9
10
11
12
13
registerTransactionManager(element, interceptorDef);
// AnnotationDrivenBeanDefinitionParser.class
private static void registerTransactionManager(Element element, BeanDefinition def) {
def.getPropertyValues().add("transactionManagerBeanName",
TxNamespaceHandler.getTransactionManagerName(element));
}
// TxNamespaceHandler.class
static String getTransactionManagerName(Element element) {
return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
}

如果tx:annotation-driven没有指定transaction-manager,系统会默认注册transactionManager

1
2
3
4
5
6
7
8
9
10
11
12
13
14
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
// AopNamespaceUtils.class
public static void registerAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element sourceElement) {
// 注册AutoProxyCreator,这里是InfrastructureAdvisorAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(sourceElement));
}
// AopConfigUtils.class
public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

实际注册的是InfrastructureAdvisorAutoProxyCreator动态代理生成器

img

前面文章介绍使用Spring Aop做切面增强,使用的是AspectJAwareAdvisorAutoProxyCreator,可见普通aop代理生成器和InfrastructureAdvisorAutoProxyCreator都是继承于AbstractAdvisorAutoProxyCreator,具体的代理生成过程参考“Spring AOP源码分析

参考

Spring源码解析之事务篇

Spring @Transactional原理及使用

Spring中AOP的配置从1.0到5.0的演进

热评文章