约 3816 字
Spring事务原理、传播机制、失效场景、分布式事务全套实现
本文全覆盖Spring事务高频核心:本地事务底层原理、四大隔离级别、七种传播机制、事务百分百失效场景、常见坑点、分布式事务问题、四种主流分布式事务实现方案,逻辑闭环、无废话、可直接背诵面试。
一、Spring本地事务核心原理
1. 事务核心本质
Spring事务是AOP动态代理实现,基于数据库事务,在目标方法执行前后:开启事务、提交事务、回滚事务。
核心机制:ThreadLocal 事务上下文绑定,同一线程共享同一个数据库连接,保证事务统一提交/回滚。
2. 事务ACID特性
- 原子性:事务要么全部成功、要么全部回滚
- 一致性:事务前后数据状态合法、完整性不变
- 隔离性:多事务并发互不干扰(隔离级别控制)
- 持久性:事务提交后数据永久落地,宕机不丢失
二、事务四大隔离级别(数据库底层)
解决并发事务三大问题:脏读、不可重复读、幻读
1. 三大并发读问题
- 脏读:读取到其他事务未提交的脏数据
- 不可重复读:同一事务内,两次读取同一数据,结果不一致(被其他事务update修改提交)
- 幻读:同一事务内,两次查询条数不一致(被其他事务insert/delete提交)
2. 四大隔离级别(从低到高)
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能 |
|---|---|---|---|---|
| READ_UNCOMMITTED(读未提交) | 存在 | 存在 | 存在 | 最高 |
| READ_COMMITTED(读已提交,Oracle默认) | 杜绝 | 存在 | 存在 | 较高 |
| REPEATABLE_READ(可重复读,MySQL默认) | 杜绝 | 杜绝 | 存在 | 中等 |
| SERIALIZABLE(串行化) | 杜绝 | 杜绝 | 杜绝 | 最低 |
注意:MySQL InnoDB 通过间隙锁+临键锁,在RR级别下杜绝大部分幻读场景。
三、Spring七种事务传播机制(面试天花板)
传播机制作用:解决事务嵌套调用时,父子事务如何传递、合并、隔离
1. 核心常用五种(必须背熟)
- REQUIRED(默认):有事务加入当前事务,无事务新建事务 (最常用)
- SUPPORTS:有事务就加入,无事务非事务运行
- MANDATORY:强制在事务内运行,无事务直接抛异常
- REQUIRES_NEW:独立新事务,挂起旧事务,互不影响(核心!嵌套事务独立回滚)
- NOT_SUPPORTED:强制非事务运行,挂起当前事务
- NEVER:强制无事务,存在事务抛异常
- NESTED:嵌套事务,依赖父事务,父回滚子必回滚,子回滚父不回滚(保存点机制)
2. 高频面试对比:REQUIRED vs NESTED vs REQUIRES_NEW
- REQUIRED:父子同一个事务,一荣俱荣一损俱损,任意异常整体回滚
- REQUIRES_NEW:完全独立两个事务,互不影响,子失败不影响父,父失败不回滚子已提交数据
- NESTED:子事务是父事务的保存点,父回滚全部回滚,子回滚只回滚子部分
四、Spring事务百分百失效场景(实战高频坑)
所有事务失效本质:AOP代理失效 / 异常未被Spring捕获 / 无事务上下文
1. 代理失效导致失效(最常见)
- 同类内部调用:本类无事务方法调用本类@Transactional方法,this调用绕过代理,事务完全失效
- 方法非public:private/protected/default 方法,Spring无法代理,事务失效
- final/static方法:无法被CGLIB/JDK代理,事务失效
2. 异常捕获不规范导致失效
- 手动try-catch捕获异常不抛出:Spring感知不到异常,不会回滚
- 抛出检查异常(Exception):Spring默认只回滚RuntimeException和Error,检查异常不回滚
解决方案:@Transactional(rollbackFor = Exception.class)
3. 数据库/配置问题导致失效
- 数据库引擎不支持事务:MyISAM不支持事务,必须InnoDB
- 事务传播机制配置错误:如NOT_SUPPORTED、NEVER强制非事务
- 多线程异步调用:子线程无法继承主线程ThreadLocal事务上下文,事务独立失效
4. 事务失效终极解决方案
- 内部调用:使用AopContext.currentProxy()获取代理对象调用
- 统一配置rollbackFor = Exception.class
- 保证事务方法public、非final、非static
- 禁止跨线程事务传递
五、分布式事务核心问题
1. 什么是分布式事务
跨多个数据库、多个服务、多个节点的事务,无法通过本地ACID保证数据一致性。
2. 分布式CAP&BASE理论(必考)
- CAP:一致性、可用性、分区容错性,三者无法同时满足,分布式场景必须舍弃C或A
- BASE:基本可用、软状态、最终一致性(互联网分布式主流方案)
3. 分布式事务痛点
本地事务只单库单连接,分布式事务跨服务跨库,出现部分成功部分失败,数据不一致
六、分布式事务四种主流实现方案(从弱到强)
1. 本地消息表(最终一致性、低耦合)
原理
业务表 + 消息表 本地事务绑定,先落库业务数据+消息数据,定时任务轮询消息表投递、重试,消费成功更新状态。
优缺点
- 优点:无中间件、简单可靠、无侵入、高可用
- 缺点:需要建表、轮询有延迟、最终一致性
适用:大多数普通业务、异步通知场景
2. RocketMQ事务消息(半消息机制)
原理
半消息预发送 → 本地事务执行 → 确认提交/回滚 → MQ投递消息,异常MQ反向回查本地事务状态。
优缺点
- 优点:无需建表、框架封装、重试可靠、最终一致
- 缺点:依赖RocketMQ、仅支持最终一致性
适用:高并发异步业务、解耦分布式事务
3. TCC事务(补偿型、强一致性、高性能)
三段式接口:Try-Confirm-Cancel
- Try:资源检查、资源锁定、预扣库存/金额
- Confirm:确认执行业务,正式提交
- Cancel:失败回滚、释放资源、补偿撤销
优缺点
- 优点:无锁、高性能、准实时一致、适合高并发
- 缺点:代码侵入极强、开发成本极高、需要幂等防悬挂
适用:支付、订单、金融核心业务
4. Seata AT模式(无侵入、主流首选)
原理(两阶段提交)
- 一阶段:执行业务SQL,自动记录undo日志、快照数据,本地事务提交
- 二阶段:全部成功则删除undo日志;任意失败则根据undo日志自动回滚
优缺点
- 优点:零代码侵入、使用简单、适配所有Spring项目、生态成熟
- 缺点:全局锁、存在数据脏写、极端场景有一致性问题
适用:90%互联网业务、微服务标准分布式事务方案
七、四种分布式事务方案终极对比(面试必背)
| 方案 | 一致性 | 性能 | 代码侵入 | 适用场景 |
|---|---|---|---|---|
| 本地消息表 | 最终一致 | 高 | 低 | 普通异步业务 |
| RocketMQ事务消息 | 最终一致 | 极高 | 极低 | 高并发异步解耦 |
| TCC | 准实时强一致 | 高 | 极高 | 金融、支付核心 |
| Seata AT | 弱一致/最终一致 | 中高 | 零侵入 | 微服务通用首选 |
八、全文终极面试总结
- 事务原理:Spring AOP代理+ThreadLocal绑定数据库连接,实现声明式事务
- 隔离级别:MySQL默认RR可重复读,解决脏读、不可重复读,规避大部分幻读
- 传播机制:默认REQUIRED共用事务,REQUIRES_NEW独立事务,NESTED嵌套保存点事务
- 失效场景:内部调用、非public、异常捕获、跨线程、引擎不支持事务
- 分布式事务:本地消息表、MQ事务消息、TCC补偿、Seata AT,根据一致性与性能选型