📌 阅读前提示 :进入 声明式事务阶段(第 25--27 篇) 。事务是 Spring 最实用的能力之一,底层却是纯 AOP (呼应第 11--14 篇)。本篇讲开关
@EnableTransactionManagement和真正干活的拦截器TransactionInterceptor------@Transactional为什么能「自动开事务、提交、回滚」。
一、引子:@Transactional 背后是 AOP
你已经知道 AOP 能在方法前后织入逻辑。@Transactional 正是用一个环绕通知 (AOP 的 @Around 等价物)包住你的方法:进入前「开启事务」,正常返回「提交」,抛异常「回滚」。
这个环绕通知就是 TransactionInterceptor。
二、@EnableTransactionManagement 注册了什么
java
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
boolean proxyTargetClass() default false; // 代理方式
AdviceMode mode() default AdviceMode.PROXY; // PROXY 或 ASPECTJ
}
TransactionManagementConfigurationSelector 导入两个关键配置:
java
// ① ProxyTransactionManagementConfiguration(核心)
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
// ★ 事务拦截器(环绕通知)
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(TransactionAttributeSource tas) {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(tas);
// transactionManager 也会被注入
return interceptor;
}
// ★ 把拦截器包装成 Advisor(BeanFactoryTransactionAttributeSourceAdvisor)
@Bean
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(...) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(tas);
advisor.setAdvice(transactionInterceptor); // ← 拦截器作为通知
return advisor;
}
}
📌 关键点 :这和 AOP 阶段完全一致------
TransactionInterceptor(通知)被包进Advisor,由AbstractAutoProxyCreator在wrapIfNecessary时匹配到@Transactional方法并生成代理(第 13 篇)。事务 = 一个特殊的 AOP Advisor。
三、TransactionInterceptor:事务环绕通知
java
// TransactionInterceptor.java
@Override
@Nullable
public Object invoke(MethodInvocation invocation) throws Throwable {
// ① 解析事务属性(@Transactional 的 propagation/isolation/timeout 等)
TransactionAttribute txAttr = determineTransactionAttribute(invocation.getMethod());
// ② 取出事务管理器
PlatformTransactionManager tm = determineTransactionManager(txAttr);
// ③ 执行:开事务 → 调目标方法 → 提交/回滚
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);
}
3.1 invokeWithinTransaction 三段式
java
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, InvocationCallback invocation) {
// 1. 创建事务(按传播行为决定新建/加入已有)
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
Object retVal;
try {
retVal = invocation.proceed(); // ★ 调用你的业务方法
} catch (Throwable ex) {
// 2. 异常 → 按 rollbackOn 规则决定回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
cleanupTransactionInfo(txInfo);
}
// 3. 正常返回 → 提交
commitTransactionAfterReturning(txInfo);
return retVal;
}
💡 重点 :事务的「提交/回滚」决策在
completeTransactionAfterThrowing------默认只有RuntimeException/Error回滚,checked Exception不回滚(可用@Transactional(rollbackFor=...)改)。
四、事务拦截器在 AOP 链中的位置

五、常见误区
| 误区 | 正解 |
|---|---|
| @Transactional 是独立机制 | 不,它是 AOP + TransactionInterceptor 包装而成 |
| 所有异常都回滚 | 仅 RuntimeException/Error 默认回滚,checked 不回滚 |
| 事务由 @EnableTransactionManagement 直接执行 | 不,它只注册 Advisor,真正执行靠 TransactionInterceptor |
| 没有事务管理器也能用 | 需 PlatformTransactionManager Bean,Boot 自动配好 |
| @Transactional 加在 private 方法生效 | 不,AOP 代理无法拦截 private(类似自调用失效,第14篇) |
🧪 面试题自测
@EnableTransactionManagement注册了哪两个核心 Bean?TransactionInterceptor在 AOP 体系里扮演什么角色?- 事务的「提交/回滚」在哪一步决策?
- 为什么 checked Exception 默认不回滚?
- 事务为什么是环绕通知而不是前置/后置?
- 事务管理器和 TransactionInterceptor 的关系?
🔧 Debug 小技巧
在 TransactionInterceptor.invokeWithinTransaction 断点,观察 txInfo 如何创建、事务状态对象里的 newTransaction 标记;再在 completeTransactionAfterThrowing 断点,故意抛异常,看 txInfo.transactionAttribute.rollbackOn(ex) 如何判定回滚。
下一篇预告
第 26 篇:事务传播行为源码------PROPAGATION_REQUIRED / REQUIRES_NEW / NESTED 等 7 种行为,在 AbstractPlatformTransactionManager.getTransaction 里到底如何决策「新建还是加入」。
如果这篇对你有帮助,欢迎 点赞 · 收藏 · 关注 三连支持。
Spring 源码系列共 30 篇,由浅入深持续更新中。有疑问或想深挖的源码点,评论区告诉我,下篇见。