一、什么是本地事务

单机数据库下,事务满足 ACID:原子性、一致性、隔离性、持久性,依靠数据库本身机制就能实现:要么全部执行成功提交,要么全部失败回滚,不会出现部分成功、部分失败的脏数据。

比如单库下单同时扣库存,要么两边都成,要么一起回滚。

二、什么是分布式事务

随着微服务拆分、分库分表,一次业务操作会跨多个服务、多个独立数据库,这就是分布式场景。

分布式事务:用来保证跨多个数据库 / 多个微服务的一组操作,整体具备原子性的解决方案。

简单一句话:跨库、跨服务的事务,要么全部成功生效,要么全部撤销回滚,不能半截执行。

举个典型场景:

下单业务拆成三个独立库:订单库、库存库、账户库

  1. 订单服务新增订单

  2. 库存服务扣减商品库存

  3. 账户服务扣减用户余额

    如果前两步成功,第三步余额扣减异常失败,就会出现:订单生成、库存变少、钱没扣,数据不一致。分布式事务就是用来杜绝这种现象,保证三操作同生同死。

三、分布式事务为什么不能直接用本地事务?

  1. 多个数据库互相独立,各自事务互不感知;
  2. 一个库提交成功后,无法主动让另一个已经提交的数据回滚;
  3. 网络超时、服务宕机、调用异常都会导致部分执行,破坏整体原子性。

四、核心目标:两种一致性

  1. 强一致性

    同一时刻所有节点数据完全一致,任何查询都看不到中间状态;典型方案:XA。

    缺点:锁持有时间长,并发性能差。

  2. 最终一致性(业界主流)

    允许短暂中间不一致,等待一段时间后,通过补偿、重试、回滚逻辑,最终所有数据达成统一;Seata AT、TCC、SAGA 都属于这类,互联网业务最常用,兼顾性能与数据安全。

五、分布式事务经典理论基础(CAP / BASE)

  1. CAP 定理

    分布式系统无法同时满足三点:

  • C 一致性:所有节点数据同步

  • A 可用性:请求正常响应

  • P 分区容错:网络故障必存在,必须满足 P

    因此只能在 CP / AP 二选一:

  • CP:放弃可用性,追求强一致(XA)

  • AP:放弃实时一致性,保证可用,用最终一致兜底(主流微服务选择)

  1. BASE 理论(AP 架构指导思想)
  • BA 基本可用:故障不会整体瘫痪,允许小幅降级

  • S 柔性状态:允许中间短暂数据不一致

  • E 最终一致:一段时间后数据自动对齐

    绝大多数分布式事务方案都是 BASE 思想落地。

六、常见分布式事务方案分类

2PC(两阶段提交)

以 XA、Seata AT 为代表,引入协调者统一调度所有资源,分准备、提交 / 回滚两阶段协调。

  • XA:数据库原生 2PC,强一致,性能差

  • Seata AT:改造版 2PC,undo_log 自动补偿,低侵入,业务最常用

TCC(Try-Confirm-Cancel)

业务层手动编写三阶段代码,手动预留资源、确认、撤销,性能高,侵入性强,多用于金融支付。

SAGA 模式

长事务补偿模式,正向执行,失败反向执行补偿接口,适合长流程、跨第三方系统事务。

本地消息表 / 可靠消息事务(事务消息)

基于 MQ 实现,通过消息投递、定时重试保证最终一致,适合异步场景,比如订单完成发积分、发通知。

最大努力通知

适用于弱一致性场景,多次重试推送,允许人工兜底,比如短信、推送通知。

七、分布式事务各模式完整业务举例

统一业务案例:下单场景

三个独立库:订单库、库存库、账户库

操作:创建订单 → 扣库存 → 扣余额

任一环节失败,三者必须整体回滚,以此演示 5 种主流方案:XA、Seata AT、TCC、SAGA、可靠消息事务。

一、XA 模式(数据库原生两阶段提交,强一致性 2PC)

1、角色
  • 协调者:事务管理器(TM)
  • 参与者:三个数据库(都支持 XA 协议,MySQL InnoDB/Oracle 等)
2、完整执行流程
阶段 1:准备阶段(Prepare)
  1. 入口服务开启全局 XA 事务,分别向订单库、库存库、账户库发送 XA START
  2. 三个数据库各自执行 SQL:插订单、扣库存、扣余额
  3. 执行完成后,各自锁定行数据,不提交事务,向协调者回复「准备就绪」
    • 只要任意一个库执行报错,直接回复「准备失败」
阶段 2:提交 / 回滚(Commit/Rollback)

情况 A:全部准备成功

协调者下发 XA COMMIT,三个数据库各自提交本地事务,释放行锁,事务结束。

情况 B:任意一个准备失败

协调者下发 XA ROLLBACK,所有数据库全部回滚本地未提交 SQL,数据全部复原。

3、异常举例

扣余额时余额不足,账户库返回准备失败 → 协调者通知订单、库存全部回滚,订单删除、库存恢复,整体一致。

4、适用场景
  • 传统银行内部系统、财务对账、老旧单体拆分的内网低并发系统

  • 内部对账、账务批量同步、对实时强一致性要求极高、并发量不大的内部业务

    不适合高并发电商:一阶段长时间持有行锁,并发堵塞严重,性能差

5、缺点
  • 锁占用时间长,高并发极易死锁、超时
  • 依赖数据库底层 XA 驱动,跨不同类型数据库兼容性差

二、Seata AT 模式(最常用,自动补偿型 2PC,最终一致性)

之前详细讲过 TM/TC/RM,快速走流程:

一阶段
  1. TM 生成全局 XID,调用订单、库存、账户三个 RM

  2. 每个 RM:记录修改前快照 before_image、执行业务 SQL、记录修改后 after_image,同本地事务写入 undo_log,提交本地事务,释放行锁

    此时数据已经真实更新到数据库,只是留有回滚日志

  3. 每个 RM 向 TC 注册分支事务

二阶段
  1. 全部正常:TC 通知所有 RM 删除各自 undo_log,事务结束
  2. 某分支异常:TC 通知所有 RM 根据 undo_log 生成逆 SQL 回滚数据,删 undo_log
场景举例

电商普通下单、大部分微服务业务,业务仅加 @GlobalTransactional 注解,零侵入开发,互联网最主流方案。


三、TCC 模式(Try-Confirm-Cancel,业务手动编码,高性能)

TCC 是业务层手动拆分三接口,不依赖数据库回滚日志,手动控制资源冻结与释放。

三个接口定义(每个微服务都要写三套代码)
  1. Try 尝试:冻结预留资源
    • 订单服务:预创建待支付订单(状态:冻结)
    • 库存服务:冻结对应商品库存(可售库存不动,冻结库存 + 1)
    • 账户服务:冻结用户对应金额(可用余额扣减,冻结余额增加)
  2. Confirm 确认:真正扣减,正式提交
    • 全局无异常,执行确认,冻结数据转为实际扣减
  3. Cancel 取消:释放冻结资源,整体回滚
    • 任意异常,解除所有冻结,恢复原有数据
完整流程
  1. TM 先调用三个服务的 Try 方法,全部冻结成功
  2. 全部 Try 成功 → 批量调用所有 Confirm,下单正式完成
  3. 任意 Try 失败 / 后续异常 → 批量调用所有 Cancel,解冻全部资源,回到初始状态
例子:余额不足场景

账户 Try 冻结余额失败 → 触发所有 Cancel:删除预订单、解冻库存、解冻资金,数据一致。

适用场景

支付交易、红包、转账、高并发秒杀、金融核心账务;

**缺点:**侵入极强,每个业务都要手写三套接口,开发维护成本很高。


四、SAGA 模式(长事务补偿模式,无前置资源冻结)

核心思想:正向一步步执行,某一步失败,反向依次执行前面步骤的补偿操作,没有准备阶段。

正向流程(正常执行)
  1. 步骤 1:创建订单
  2. 步骤 2:扣减库存
  3. 步骤 3:扣减余额
补偿接口(逆向回滚用)
  • 补偿 1:取消订单(删除 / 作废订单)
  • 补偿 2:回退库存(加回被扣库存)
  • 补偿 3:退款(退回被扣余额)
异常演示

执行到第三步扣余额失败:

  1. 执行步骤 2 的补偿:把库存加回去
  2. 执行步骤 1 的补偿:取消订单,最终整体回滚。
两种实现方式
  1. 编排式:单独一个事务协调中心编排每一步与补偿逻辑
  2. 编排式:服务之间事件监听互相调用
适用场景

超长业务流程:订单履约、物流发货、售后退款、多级审批、跨第三方外部系统(对接第三方支付、快递、外部 ERP);

**特点:**无锁、适合长耗时事务;缺点存在中间态脏数据,只有最终一致性。


五、可靠消息事务(本地消息表 / MQ 事务消息,异步最终一致)

适合异步场景,不是实时同步事务。

业务流程(下单后发积分举例,也可用于下单一致性)

需求:订单创建成功,才给用户加积分;订单失败,不能加积分。

  1. 本地事务:订单库插入订单 + 消息表插入一条待发送消息,同库事务一起提交
  2. 定时任务轮询消息表,把消息发送到 MQ
  3. 积分服务消费 MQ 消息,执行加积分
  4. 消费失败则不断重试,保证最终投递;消息投递失败定时补发,防止消息丢失
下单一致性改造思路
  1. 先创建订单,写入待扣库存消息
  2. MQ 消费消息扣库存、扣余额
  3. 任一消费失败,重试 + 死信人工兜底
适用场景

异步解耦场景:下单发短信、发积分、会员成长值、通知推送、数据同步;

不适合强实时同步转账、下单强同步扣库存场景。


快速横向对比总结
模式 一致性 锁特点 侵入性 典型使用场景
XA 强一致 一阶段持有行锁,性能差 极低 内网财务对账、传统内部账务系统、低并发内部业务
Seata AT 最终一致 全局锁防脏写,一阶段释放本地锁,性能好 极低(注解) 绝大多数微服务同步下单、进销存业务(主流首选)
TCC 最终一致 业务层冻结资源,无数据库长锁,性能最优 极高(三接口手写) 支付、转账、红包、秒杀、金融核心交易
SAGA 最终一致 无资源预留锁,允许中间不一致 中等(写补偿接口) 长流程履约、售后、物流、跨外部第三方系统
可靠消息 最终一致 无锁,异步执行 异步通知、积分、数据同步、解耦类业务

更多推荐