Spring事务原理、传播机制、失效场景、分布式事务全套实现

约 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,根据一致性与性能选型