事务自动配置
概述
Spring Boot 通过 TransactionAutoConfiguration 和 DataSourceTransactionManagerAutoConfiguration 自动配置事务管理基础设施,核心包括 PlatformTransactionManager 实现、@Transactional 注解支持、@TransactionalEventListener 事务绑定等。
本文将拆解事务自动配置的 8 个关键细节,涵盖条件注解、代理模式、拦截器实现、事务同步等核心内容。
本文基于 Spring Boot 3.2.5 + Spring Framework 6.1.6 源码分析。
1. DataSourceTransactionManagerAutoConfiguration 的条件
DataSourceTransactionManagerAutoConfiguration 是事务自动配置的入口之一,其触发有两个条件:
@AutoConfiguration(after = DataSourceAutoConfiguration.class)
@ConditionalOnClass(JdbcTemplate.class)
@ConditionalOnSingleCandidate(DataSource.class)
public class DataSourceTransactionManagerAutoConfiguration {
// ...
}| 条件 | 说明 |
|---|---|
@AutoConfiguration(after = DataSourceAutoConfiguration.class) | 确保在 DataSource 自动配置之后执行 |
@ConditionalOnClass(JdbcTemplate.class) | classpath 中存在 JdbcTemplate(spring-jdbc 依赖) |
@ConditionalOnSingleCandidate(DataSource.class) | 容器中存在且只有一个 DataSource Bean |
当上述条件满足时,该配置类会注册一个 DataSourceTransactionManager Bean:
@Bean
@ConditionalOnMissingBean(PlatformTransactionManager.class)
DataSourceTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}@ConditionalOnMissingBean(PlatformTransactionManager.class) 确保用户自定义的 PlatformTransactionManager 不会被覆盖。
2. TransactionAutoConfiguration 的 TransactionTemplate 创建
TransactionAutoConfiguration 在 DataSourceTransactionManagerAutoConfiguration 之后运行,它自动创建一个 TransactionTemplate Bean:
@AutoConfiguration(after = {TransactionManagerCustomizationAutoConfiguration.class})
@ConditionalOnClass(PlatformTransactionManager.class)
public class TransactionAutoConfiguration {
@Bean
@ConditionalOnMissingBean
TransactionTemplate transactionTemplate(PlatformTransactionManager transactionManager) {
return new TransactionTemplate(transactionManager);
}
}TransactionTemplate 是编程式事务的核心工具类,封装了 PlatformTransactionManager,提供以下方法:
execute(TransactionCallback<T> action)— 执行带返回值的事务操作executeWithoutResult(Consumer<TransactionStatus> action)— 执行无返回值的事务操作setPropagationBehavior()/setIsolationLevel()— 配置传播行为和隔离级别
使用示例:
@Autowired
private TransactionTemplate transactionTemplate;
public void doSomething() {
transactionTemplate.executeWithoutResult(status -> {
// 事务内的操作
jdbcTemplate.update("UPDATE ...");
if (error) {
status.setRollbackOnly(); // 手动回滚
}
});
}3. EnableTransactionManagementCglibProxyConfiguration 的 CGLIB 代理
EnableTransactionManagementCglibProxyConfiguration 控制 @Transactional 的代理模式:
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public class EnableTransactionManagementCglibProxyConfiguration {
// ...
}关键点:
| 配置 | 说明 |
|---|---|
@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class") | 读取 spring.aop.proxy-target-class 配置项 |
havingValue = "true" | 仅当值为 true 时匹配 |
matchIfMissing = true | 默认使用 CGLIB 代理 |
这意味着在 Spring Boot 3.x 中,即使没有配置 spring.aop.proxy-target-class=true,也会默认启用 CGLIB 代理(而非 JDK 动态代理)。
CGLIB 代理 vs JDK 动态代理:
| 对比维度 | CGLIB | JDK 动态代理 |
|---|---|---|
| 实现方式 | 字节码增强生成子类 | 接口反射生成代理对象 |
| 要求 | 类不能是 final | 必须实现接口 |
| 默认使用 | Spring Boot 3.x 默认 | Spring Boot 2.x 可配置 |
4. ProxyTransactionManagementConfiguration 注册 3 个 Bean
@EnableTransactionManagement 通过 ProxyTransactionManagementConfiguration 向容器注册 3 个核心 Bean,这是 @Transactional 注解生效的基础:
@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
TransactionAttributeSource transactionAttributeSource,
TransactionInterceptor transactionInterceptor) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
advisor.setAdvice(transactionInterceptor);
advisor.setOrder(Ordered.LOWEST_PRECEDENCE); // 最低优先级
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(
TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource);
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}三个 Bean 的分工:
| Bean | 角色 |
|---|---|
BeanFactoryTransactionAttributeSourceAdvisor | 配置切面(Advice + Pointcut) |
TransactionAttributeSource(实际为 AnnotationTransactionAttributeSource) | 解析 @Transactional 注解属性 |
TransactionInterceptor | 事务拦截器,负责事务的开启/提交/回滚 |
5. TransactionInterceptor.invoke() 的事务包裹
TransactionInterceptor 是 @Transactional 的方法级拦截器,继承自 TransactionAspectSupport。其核心调用链如下:
// TransactionInterceptor.invoke()
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = AopUtils.getTargetClass(invocation.getThis());
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
// TransactionAspectSupport.invokeWithinTransaction()
protected Object invokeWithinTransaction(Method method, Class<?> targetClass, InvocationCallback invocation) {
// 1. 获取事务属性
TransactionAttributeSource tas = getTransactionAttributeSource();
TransactionAttribute txAttr = tas.getTransactionAttribute(method, targetClass);
// 2. 确定 PlatformTransactionManager
PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 3. 创建事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try {
// 4. 执行目标方法
retVal = invocation.proceedWithInvocation();
} catch (Throwable ex) {
// 5. 异常时事务回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
// 6. 清理事务信息
cleanupTransactionInfo(txInfo);
}
// 7. 正常提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}核心流程:
@Transactional 方法被调用
↓
TransactionInterceptor.invoke()
↓
TransactionAspectSupport.invokeWithinTransaction()
↓
createTransactionIfNecessary() — 创建/加入事务
↓
目标方法执行
├── 成功 → commitTransactionAfterReturning()
└── 异常 → completeTransactionAfterThrowing()createTransactionIfNecessary() 内部逻辑:
protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm,
TransactionAttribute txAttr, String joinpointIdentification) {
// 1. 从 TransactionSynchronizationManager 获取当前事务
// 2. 根据传播行为决定:新建/挂起/加入
// 3. 返回 TransactionInfo 封装事务状态
TransactionStatus status = tm.getTransaction(txAttr);
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);
}传播行为处理(7 种):
| 传播行为 | getTransaction() 处理逻辑 |
|---|---|
REQUIRED(默认) | 有则加入,无则新建 |
REQUIRES_NEW | 挂起当前事务,新建事务 |
SUPPORTS | 有则加入,无则非事务执行 |
NOT_SUPPORTED | 挂起当前事务,非事务执行 |
NEVER | 有事务则抛异常 |
MANDATORY | 无事务则抛异常 |
NESTED | 使用 Savepoint 创建嵌套事务 |
6. BeanFactoryTransactionAttributeSourceAdvisor 的切点匹配
BeanFactoryTransactionAttributeSourceAdvisor 是一个 Advisor,它通过 TransactionAttributeSourcePointcut 实现切点匹配:
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
private TransactionAttributeSource transactionAttributeSource;
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
@Override
public Pointcut getPointcut() {
return new TransactionAttributeSourcePointcut() {
@Override
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;
}
};
}
}TransactionAttributeSourcePointcut.matches() 实现:
class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut {
@Override
public boolean matches(Method method, Class<?> targetClass) {
TransactionAttributeSource tas = getTransactionAttributeSource();
// 调用 AnnotationTransactionAttributeSource 解析方法上是否有 @Transactional
TransactionAttribute txAttr = tas.getTransactionAttribute(method, targetClass);
return txAttr != null; // 有事务属性才匹配
}
}AnnotationTransactionAttributeSource 解析流程:
matches(method, targetClass)
↓
AnnotationTransactionAttributeSource.getTransactionAttribute()
↓
computeTransactionAttribute()
├── 1. 检查目标方法上的 @Transactional
├── 2. 检查目标类上的 @Transactional
├── 3. 检查接口方法上的 @Transactional
└── 4. 检查接口类上的 @Transactional
↓
返回 TransactionAttribute 或 null7. @TransactionalEventListener 的事务绑定
@TransactionalEventListener 是基于 Spring 事件机制 + 事务同步的扩展,允许事件监听器在事务的特定阶段执行。
@Component
public class OrderEventListener {
@TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
public void handleOrderCreated(OrderCreatedEvent event) {
// 当事务成功提交后执行
sendNotification(event.getOrderId());
}
}支持的事务阶段:
phase 值 | 执行时机 |
|---|---|
AFTER_COMMIT(默认) | 事务成功提交后 |
AFTER_ROLLBACK | 事务回滚后 |
AFTER_COMPLETION | 事务完成(提交或回滚)后 |
BEFORE_COMMIT | 事务提交前 |
核心实现 —— TransactionSynchronizationManager 注册事务同步回调:
// TransactionalEventListenerFactory 创建代理
public class ApplicationListenerMethodTransactionalAdapter
implements ApplicationListener<ApplicationEvent>, TransactionalApplicationListener {
@Override
public void onApplicationEvent(ApplicationEvent event) {
// 若非事务环境或事务已完成,直接执行
if (!TransactionSynchronizationManager.isSynchronizationActive()) {
invokeListener(event);
return;
}
// 注册事务同步回调
TransactionSynchronizationManager.registerSynchronization(
new TransactionSynchronizationEventAdapter(this, event, phase));
}
}TransactionSynchronizationEventAdapter 实现:
class TransactionSynchronizationEventAdapter implements TransactionSynchronization {
private final ApplicationListenerMethodTransactionalAdapter adapter;
private final ApplicationEvent event;
private final TransactionPhase phase;
@Override
public void afterCommit() {
if (phase == TransactionPhase.AFTER_COMMIT || phase == TransactionPhase.AFTER_COMPLETION) {
adapter.processEvent(event);
}
}
@Override
public void afterCompletion(int status) {
if (status == STATUS_ROLLED_BACK && phase == TransactionPhase.AFTER_ROLLBACK) {
adapter.processEvent(event);
}
if (phase == TransactionPhase.AFTER_COMPLETION) {
adapter.processEvent(event);
}
}
@Override
public void beforeCommit(boolean readOnly) {
if (phase == TransactionPhase.BEFORE_COMMIT) {
adapter.processEvent(event);
}
}
}完整流程:
发布事件(如 orderCreatedEvent)
↓
ApplicationListenerMethodTransactionalAdapter.onApplicationEvent()
↓
TransactionSynchronizationManager.registerSynchronization()
↓ (事务提交时)
TransactionSynchronization.afterCommit() / beforeCommit()
↓
执行 @TransactionalEventListener 方法8. 多 PlatformTransactionManager 时 @Transactional("tmName") 的原理
当应用中存在多个 PlatformTransactionManager Bean 时,需要通过 @Transactional("tmName") 指定使用哪个事务管理器。
配置示例:
@Configuration
public class TransactionManagerConfig {
@Bean
@Primary
public PlatformTransactionManager primaryTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public PlatformTransactionManager secondaryTransactionManager(DataSource secondaryDataSource) {
return new DataSourceTransactionManager(secondaryDataSource);
}
}使用:
@Service
public class OrderService {
@Transactional("primaryTransactionManager")
public void doPrimary() { /* 主库事务 */ }
@Transactional("secondaryTransactionManager")
public void doSecondary() { /* 从库事务 */ }
}实现原理:
AnnotationTransactionAttributeSource 解析 @Transactional 时,会获取 value 或 transactionManager 属性(两者互为别名):
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
}TransactionAspectSupport.determineTransactionManager() 根据这个名称从 BeanFactory 获取对应的 PlatformTransactionManager:
protected PlatformTransactionManager determineTransactionManager(TransactionAttribute txAttr) {
String qualifier = txAttr.getQualifier(); // @Transactional 的 value/transactionManager
if (StringUtils.hasText(qualifier)) {
// 根据 qualifier 从 BeanFactory 获取指定名称的 TransactionManager
return getBeanFactory().getBean(qualifier, PlatformTransactionManager.class);
}
// 无指定名称时使用默认的 TransactionManager
if (this.transactionManager != null) {
return this.transactionManager;
}
// 最后通过 TransactionManagementConfigurer 获取默认 TM
return this.defaultTransactionManager;
}默认 TM 的确定:
如果 @Transactional 未指定名称,且 TransactionInterceptor 未注入 transactionManager,则通过 TransactionManagementConfigurer 配置默认 TM:
@Configuration
public class MyTransactionManagementConfigurer implements TransactionManagementConfigurer {
@Autowired
@Qualifier("primaryTransactionManager")
private PlatformTransactionManager txManager;
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager;
}
}总结
事务自动配置的 8 个细节点总结如下:
| # | 细节点 | 核心类/机制 |
|---|---|---|
| ① | DataSourceTransactionManagerAutoConfiguration 的条件 | @ConditionalOnClass(JdbcTemplate.class) + @ConditionalOnSingleCandidate(DataSource.class) |
| ② | TransactionAutoConfiguration 的 TransactionTemplate 创建 | new TransactionTemplate(transactionManager) 自动注入 |
| ③ | EnableTransactionManagementCglibProxyConfiguration 的 CGLIB 代理 | @ConditionalOnProperty("spring.aop.proxy-target-class") 默认 CGLIB |
| ④ | ProxyTransactionManagementConfiguration 注册 3 个 Bean | BeanFactoryTransactionAttributeSourceAdvisor + TransactionInterceptor + TransactionAttributeSource |
| ⑤ | TransactionInterceptor.invoke() 的事务包裹 | TransactionAspectSupport.invokeWithinTransaction() → createTransactionIfNecessary() |
| ⑥ | BeanFactoryTransactionAttributeSourceAdvisor 的切点匹配 | TransactionAttributeSourcePointcut.matches() → AnnotationTransactionAttributeSource |
| ⑦ | @TransactionalEventListener 的事务绑定 | TransactionSynchronizationManager.registerSynchronization() 注册事务同步回调 |
| ⑧ | 多 PlatformTransactionManager 时 @Transactional("tmName") 的原理 | determineTransactionManager() 根据 qualifier 获取指定 TM |