Spring 事务底层原理
划分处理单元 IOC
由于 Spring 解决的问题是对单个数据库进行局部事务处理的,具体的实现首相用 Spring 中的 IOC 划分了事务处理单元。并且将对事务的各种配置放到了 IOC 容器中(设置事务管理器,设置事务的传播特性及隔离机制)。
AOP 拦截需要进行事务处理的类
Spring 事务处理模块是通过 AOP 功能来实现声明式事务处理的,具体操作(比如事务实行的配置和读取,事务对象的抽象),用 TransactionProxyFactoryBean 接口来使用 AOP 功能,生成 proxy 代理对象,通过 TransactionInterceptor 完成对代理方法的拦截,将事务处理的功能编织到拦截的方法中。读取 IOC 容器事务配置属性,转化为 Spring 事务处理需要的内部数据结构(TransactionAttributeSourceAdvisor),转化为 TransactionAttribute 表示的数据对象。
对事物处理实现(事务的生成、提交、回滚、挂起)
Spring 委托给具体的事务处理器实现。实现了一个抽象和适配。适配的具体事务处理器:DataSource 数据源支持、Hibernate 数据源事务处理支持、JDO 数据源事务处理支持,JPA、JTA 数据源事务处理支持。这些支持都是通过设计 PlatformTransactionManager、AbstractPlatforTransaction 一系列事务处理的支持。 为常用数据源支持提供了一系列的 TransactionManager。
结合
PlatformTransactionManager 实现了 TransactionInterception 接口,让其与 TransactionProxyFactoryBean 结合起来,形成一个 Spring 声明式事务处理的设计体系。
IOC 划分 + AOP 拦截 + 事务管理器适配三层骨架正确,但现代实现细节已演进(注解驱动替代 TransactionProxyFactoryBean),且还缺一块最核心的机制:事务上下文如何与线程/连接绑定(TransactionSynchronizationManager)。本文补全链路,把”注解生效到 SQL 提交”的每一步落到对象级。
现代链路:从 @Transactional 到代理
- 解析:AnnotationTransactionAttributeSource 读取方法/类上的 @Transactional,封装为 TransactionAttribute(传播/隔离/超时/只读/回滚规则)
- 匹配:BeanFactoryTransactionAttributeSourceAdvisor(一个 Advisor)以”是否有 TransactionAttribute”为 pointcut 匹配 bean
- 代理:匹配成功的 bean 在初始化后被织入代理,拦截器为 TransactionInterceptor
- 执行:代理方法调用进入 TransactionInterceptor.invoke → 委托 TransactionAspectSupport.invokeWithinTransaction
invokeWithinTransaction 的六步
// 伪码主线 |
createTransactionIfNecessary 内部按传播行为决策:REQUIRED 查当前线程有无事务(有则加入)、REQUIRES_NEW 挂起当前事务新开、NESTED 建保存点等——传播语义全部在这一分支里实现。
线程绑定:TransactionSynchronizationManager
事务的”当前连接”存在哪?答案是一个基于 ThreadLocal 的资源持有器:
DataSourceTransactionManager.doBegin:从连接池取 Connection,setAutoCommit(false),绑定到 TransactionSynchronizationManager 的 ThreadLocalMap(key=DataSource)- 业务中 JdbcTemplate/MyBatis 获取连接时,先查 ThreadLocal:同线程同 DataSource 拿到同一个 Connection——这就是”一个事务一个连接”的保证
- 提交/回滚后解绑、恢复 autoCommit、归还连接
这也解释了多线程失效的根因:子线程查不到父线程 ThreadLocal 里的连接,自然不在同一事务。
挂起与恢复(REQUIRES_NEW / NESTED)
- REQUIRES_NEW:suspend 把当前 TransactionInfo 与连接绑定从 ThreadLocal 摘除保存 → 新开连接与事务 → 内层结束后 resume 恢复外层绑定。内外层是两个独立 Connection、两个独立事务
- NESTED:同一连接上
SAVEPOINT,内层回滚只滚到保存点,外层提交时一并提交
回滚规则与标记
completeTransactionAfterThrowing 判断:异常类型匹配 rollbackFor/noRollbackFor 规则 → tm.rollback;否则提交。另支持 setRollbackOnly():在 TransactionStatus 上打标记,提交时检查标记强制回滚(编程式控制点)。
事务管理器家族(适配层)
- DataSourceTransactionManager:单 JDBC 数据源(最常用)
- JpaTransactionManager / HibernateTransactionManager:ORM 会话与事务联动
- JtaTransactionManager:跨多资源(多数据源/MQ)的 JTA/XA 分布式事务
- 抽象基类 AbstractPlatformTransactionManager 固化了 begin/commit/rollback 模板流程(模板方法模式),子类只实现 doBegin/doCommit/doRollback
一张图总结
@Transactional |
底层原理的主线:AOP 提供拦截点、TransactionAttribute 携带规则、传播行为决定事务拓扑、ThreadLocal 绑定连接保证同事务同连接、管理器适配不同数据源。五者各管一段,声明式事务才是”一个注解”背后完整的协作体系。











