spring事务原理核心是aop织入、platformtransactionmanager和数据库事务联动三环:@transactional通过代理对象(jdk/cglib)交由transactioninterceptor处理,事务状态用threadlocal绑定;platformtransactionmanager统一接口,datasourcetransactionmanager基于jdbc控制事务;传播行为和隔离级别由事务管理器动态决策并最终作用于数据库连接。

学 Spring 事务底层原理,关键不是死记概念,而是顺着“谁干了什么、怎么串起来”的线索一层层拆解。核心就三块:AOP 织入、事务管理器(PlatformTransactionManager)、数据库事务联动。掌握这三环,原理就立住了。
从 @Transactional 到代理对象:看清 AOP 是怎么介入的
Spring 不会直接执行你的 @Transactional 方法,而是生成一个代理对象来包裹它。这个代理在方法调用前后自动加事务逻辑。
- 有接口时用 JDK 动态代理,没接口时用 CGLIB 生成子类——代理对象才是真正被 Spring 容器管理的 Bean
- 真正起作用的是 TransactionInterceptor,它在 invoke() 里解析 @Transactional 的传播行为、隔离级别等属性
- 事务状态(比如是否新事务、是否已标记回滚)通过 ThreadLocal 绑定到当前线程,保证同一线程内事务上下文不混乱
PlatformTransactionManager 是事务操作的实际执行者
它不是具体实现,而是一套统一接口,屏蔽了 JDBC、JPA、Hibernate 等不同技术的差异。
- DataSourceTransactionManager 最常用,底层靠 JDBC Connection 的 setAutoCommit(false)、commit()、rollback() 控制事务
- getTransaction() 返回 TransactionStatus,里面封装了连接、保存点、是否只读等运行时状态
- commit() 和 rollback() 并非总触发数据库操作——比如嵌套事务(NESTED)可能只释放保存点,而不真正提交
事务传播行为和隔离级别到底怎么生效
这些不是注解写完就自动生效的,而是由事务管理器结合当前执行环境动态决策的。
- REQUIRED:先查当前线程有没有活跃事务,有就复用,没有才新建——依赖 TransactionStatus 中的 isExistingTransaction 标志
- REQUIRES_NEW:强制挂起当前事务(存到 SuspendedResourcesHolder),再开新事务;方法结束再恢复原事务
- 隔离级别最终会转成 Connection.setTransactionIsolation() 调用,但实际效果取决于数据库引擎支持(如 MySQL InnoDB 支持 READ_COMMITTED 和 REPEATABLE_READ)
动手验证比看十遍源码更有效
光读理论容易飘,建议用最小可运行代码验证关键路径:
- 在 @Transactional 方法里打断点,观察调用栈里是否有 TransactionInterceptor.invoke()
- 配置日志级别为 DEBUG(org.springframework.transaction),看控制台输出的 “Creating new transaction” 或 “Participating in existing transaction”
- 故意抛出 RuntimeException,确认数据库变更是否真的回滚;换成 Exception 再试一次,看是否不回滚(默认只对 unchecked 异常回滚)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











