——从“钱没扣完但库存没了”的血案说起
1. 引子:为什么你必须懂分布式事务?
在传统单体系统里,一个 begin-commit 就能解决的问题,
到了分布式系统中,直接升级成了“灾难现场”。
最经典的血案:
用户下单 → 支付扣款成功
但由于库存服务失败,钱扣了、货却没了
这就是分布式事务问题。
处理不好,不仅用户骂,财务对不上账,还可能一锅业务全崩。
2. 什么是分布式事务?
一句话解释:
一个跨多个系统(服务/数据库)的操作,要么都成功,要么都失败。
核心挑战在于:
- 每个系统独立运行,之间通过网络通信
- 失败/超时/丢包随时可能发生
本质上:
我怎么在“多个数据库/服务”之间,保证数据一致性?
四种分布式事务方案对比
方案 | 一致性 | 是否阻塞 | 常见应用场景 |
| 2PC | 强一致 | 是 | 银行转账、支付系统 |
| TCC | 强一致 | 否 | 锁定资源类业务(库存、酒店预订) |
| 事务消息 | 最终一致 | 否 | 电商下单、日志系统 |
| SAGA | 最终一致 | 否 | 长流程业务(订单流转、审批流程)
3. CAP 与分布式事务的关系?
CAP 定理说:在一致性、可用性、分区容错中,最多只能同时满足两个。
大多数微服务架构,优先选的是:
- P:分区容错性(必须有)
- A:高可用(业务不能卡死)
牺牲的一致性怎么办?
👉 就靠分布式事务机制来“补一致”。
4. 四大主流分布式事务方案
🔵 ① 2PC(Two-Phase Commit)
流程:
- 准备阶段:所有子服务执行“预提交”操作,返回“可以提交/失败”
- 提交阶段:协调者统一发起“提交” or “回滚”命令
优点:理论上强一致
缺点:性能差、易阻塞、单点问题多
👉 小比喻:集体跳水前要全部“准备好了”才能跳,否则全都不上
事务协调器发送prepare
↓
各子服务执行本地事务(预提交)
↓
全部成功?
↓
是:发送commit提交 | 否:发送rollback回滚
🔵 ② TCC(Try-Confirm-Cancel)
流程:
- Try:预留资源(比如锁库存)
- Confirm:真正执行提交操作
- Cancel:释放资源,回滚操作
Try阶段(资源预留)
↓
Confirm阶段(真正提交)
↓
Cancel阶段(撤销补偿)
每个参与方都需要实现 三段逻辑
优点:粒度清晰、灵活控制
缺点:代码复杂、补偿逻辑重
👉 小比喻:你订了酒店(Try),决定入住(Confirm),或者临时不住了(Cancel)
🔵 ③ 本地消息表 + 事务消息(异步最终一致性)
流程:
- 本地事务操作 + 写消息表
- 异步投递消息给下游服务
- 下游处理成功后回调确认,失败则重试/人工补偿
常见技术:RocketMQ事务消息、Canal监听Binlog等
优点:不阻塞主流程
缺点:一致性是最终一致性
👉 小比喻:你发了邮件,下游“迟点”才处理,靠通知机制确认处理情况
基于消息表的事务处理流程图
本地事务成功(操作+写入消息表)
↓
异步发送消息到MQ
↓
下游服务消费消息
↓
确认消费成功 or 触发补偿机制
🔵 ④ SAGA模式(长事务编排)
流程:
- 拆成多个本地事务,每个事务都配一个“补偿操作”
- 中间服务(事务协调器)负责流程控制:失败后逐步回滚
适合:长链路业务(比如电商订单流程)
常用工具:Seata、Axon、LRA等
👉 小比喻:一次“旅行计划”,中途每个步骤都能撤销,协调者安排整个流程
本地事务1
↓ 成功
本地事务2
↓ 成功
本地事务3
↓ 失败
补偿事务2 → 补偿事务1
5. 面试中常问:如何选择分布式事务方案?
| 方案 | 一致性等级 | 是否阻塞 | 场景适配 |
|---|---|---|---|
| 2PC | 强一致性 | 是 | 银行、支付、核心账户系统 |
| TCC | 强一致性 | 否 | 锁资源类,如库存、房间 |
| 事务消息 | 最终一致性 | 否 | 业务解耦、对时效要求不高 |
| SAGA | 最终一致性 | 否 | 订单流转、长链流程业务 |
6. 如何落地?(以 Seata + SpringBoot 为例)
简单集成流程:
- 引入 Seata 依赖
- 配置注册中心、事务协调器
- 各子服务使用
@GlobalTransactional - 配置 undo_log 表用于回滚追踪
@GlobalTransactional
public void createOrder() {
// 扣减库存
// 扣除余额
// 记录订单
}
👉 小提示:操作越多、服务越多,越适合自动补偿型框架(如Seata)
7. 常见问题 ⚠️
| 问题 | 原因 |
|---|---|
| 消息重复消费 | 没做好幂等控制 |
| 回滚失败 | 补偿逻辑写错 or 网络异常 |
| 主服务提交成功但分支挂了 | 事务协调不及时,补偿机制缺失 |
| 事务日志暴增 | undo_log未清理、执行慢 |
8. 彩蛋:一句话总结四种方案
2PC要等全体准备、TCC自己三段搞定、消息队列靠异步、SAGA编排长流程。
背下来,无论写方案文档还是面试答题,都直接一锤定音!
分布式事务选择建议图卡
✅ 追求强一致性 → 2PC / TCC
✅ 能容忍短暂不一致 → 消息队列 / SAGA
✅ 极致高性能 → 事务消息优先
✅ 流程超复杂 → SAGA编排更好控