分布式事务的 5 种解决方案(电商下单必看)
【决策层速查 · 30 秒读完】
分布式事务 = 跨服务数据一致性。
电商下单涉及订单/库存/支付/优惠券 4 个系统,任何一个失败都要回滚。
5 种主流方案:2PC / TCC / Saga / 本地消息表 / 最大努力通知。
分布式事务的 5 种解决方案(电商下单必看)
一、为什么电商系统必须解决分布式事务?
一个完整的电商下单流程涉及 4 个独立服务:
- 订单服务:创建订单
- 库存服务:扣减库存
- 支付服务:调用支付网关
- 优惠券服务:核销优惠券
如果用传统单体的方式(一个数据库 + 事务 ACID),这 4 步要么全部成功要么全部回滚。但在微服务架构下,每个服务有独立数据库,传统的 ACID 事务就不够了——这就是分布式事务问题。
二、5 种方案对比
| 方案 | 一致性 | 性能 | 复杂度 | 适用场景 |
|---|---|---|---|---|
| 2PC | 强 | 差 | 低 | 传统金融 |
| TCC | 最终 | 中 | 高 | 核心交易 |
| Saga | 最终 | 好 | 中 | 长事务流程 |
| 本地消息表 | 最终 | 好 | 低 | 异步通知 |
| 最大努力通知 | 弱 | 最好 | 最低 | 对账/补偿 |
三、5 种方案详解
3.1 两阶段提交(2PC)
原理:
- 阶段 1(Prepare):协调者询问所有参与者"能否提交?",所有参与者锁定资源并返回"OK"
- 阶段 2(Commit/Rollback):如果所有参与者都"OK",协调者下令提交;否则下令回滚
优点:强一致性
缺点:
- 同步阻塞(所有参与者等待协调者指令)
- 协调者单点故障(一旦挂掉整个系统卡住)
- 性能差(不适合高并发电商场景)
适用:传统金融系统,对一致性要求极高、性能要求低
3.2 TCC(Try-Confirm-Cancel)
原理:业务层面拆成 3 步
- Try:预留资源(冻结库存、冻结优惠券、冻结金额)
- Confirm:确认执行(实际扣减库存、核销优惠券)
- Cancel:取消预留(解冻库存、解冻优惠券)
优点:最终一致性 + 性能可控
缺点:业务侵入性强(每个业务都要写 Try/Confirm/Cancel 3 个方法)
适用:电商核心交易(订单/支付/库存扣减)
3.3 Saga 模式
原理:把长事务拆成多个本地事务,每个本地事务都有对应的补偿操作。
举例(下单流程):
- T1:创建订单 → 失败则中止
- T2:扣减库存 → 失败则补偿(删除订单)
- T3:扣减金额 → 失败则补偿(恢复库存 + 删除订单)
- T4:发送通知 → 失败可容忍(异步重试)
优点:性能好、适合长事务
缺点:补偿逻辑复杂、要处理"中间状态可见"
适用:跨境支付、跨行转账等长流程
3.4 本地消息表(最常用)
原理:
- 服务 A 在本地事务中插入业务数据 + 消息表记录
- 后台轮询消息表,把消息发给 MQ
- 服务 B 消费 MQ 消息,完成业务
优点:实现简单、性能好、保证最终一致
缺点:有延迟(取决于轮询频率)
适用:下单成功后发短信、发推送、扣减积分等异步场景
3.5 最大努力通知
原理:调用方主动重试,被调用方做好幂等性保证。不保证 100% 一致,但能保证"最终大部分成功"。
优点:最简单、性能最好
缺点:可能漏单,需要人工对账补偿
适用:对账、第三方回调、补偿任务
四、电商场景实战建议
电商系统通常混合使用多种方案:
| 场景 | 推荐方案 |
|---|---|
| 订单 + 库存 + 支付 | TCC(强保证) |
| 订单成功后发通知 | 本地消息表 |
| 跨行转账 | Saga |
| 对账任务 | 最大努力通知 |
| 积分 / 优惠券核销 | TCC + 本地消息表 组合 |
五、常见误区
误区 1:分布式事务能 100% 一致
除了 2PC 强一致性,其他方案都是最终一致。在极端情况下(比如机房断电),可能存在短暂不一致。
误区 2:所有场景都用 TCC
TCC 业务侵入性强、对开发能力要求高。不该用 TCC 的场景强行用 TCC = 增加复杂度。
误区 3:分布式事务能解决所有数据问题
分布式事务只能解决跨服务数据一致性,解决不了数据丢失 / 数据错误 / 业务逻辑 bug。后者需要业务系统自身的设计和测试。
联系方式:400-025-0992
