[面试题] Spring 的声明式事务是如何实现的?
📖 版块 A:知识讲解版 (温故知新)
-
核心结论:
- Spring 声明式事务本质上是 AOP + TransactionInterceptor + PlatformTransactionManager。
-
实现主线:
@Transactional被解析成事务属性元数据。- Spring 在容器启动阶段注册事务相关基础设施和自动代理能力。
- 对命中事务切点的方法生成代理。
- 调用方法时,由
TransactionInterceptor在前后织入开启事务、提交事务、回滚事务的逻辑。
-
TransactionManager 的职责:
- 根据底层资源类型管理事务。
- 比如
DataSourceTransactionManager会围绕 JDBC Connection 做事务开启、提交和回滚。
-
一个很重要的点:
- Spring 事务本质上还是依附于底层资源事务能力。
- 如果底层是 JDBC,那最终一定绕不开 DataSource 和 Connection。
🎤 版块 B:面试实战版 (高手逐字稿)
Q:Spring 的声明式事务是如何实现的?
💬 高手逐字稿:
Spring 的声明式事务,本质上就是 AOP 在事务场景下的一次具体落地。
简单来说,你在方法上加了 @Transactional,Spring 不会去改你的业务代码,而是会在容器启动时把这个方法识别成一个需要事务增强的切点。后面当这个 Bean 被创建时,Spring 会为它生成代理对象。等真正调用这个方法时,进来的其实是代理对象而不是原始对象。
这个代理对象里最核心的增强器就是 TransactionInterceptor。它会在目标方法执行前后织入事务逻辑,典型流程是这样的:
- 先读取当前方法对应的事务属性;
- 判断当前线程有没有现成事务;
- 根据传播行为决定是加入、挂起还是新建事务;
- 通过
PlatformTransactionManager开启事务; - 执行业务方法;
- 正常就提交,异常就根据规则决定是否回滚。
如果底层是 JDBC 场景,那最常见的实现就是 DataSourceTransactionManager。它本质上还是围绕 DataSource 获取到的 Connection 在工作,比如关闭自动提交、执行 commit、执行 rollback。也就是说,Spring 事务虽然表面上看起来是一个注解,但底层最终还是在管理数据库连接的事务状态。
所以我一般会把 Spring 声明式事务总结成一句话:Spring 用 AOP 拦住方法调用,再把事务管理器插进去,最终把事务控制落实到底层 Connection 上。
最后更新于: