939 字
约 3 分钟
9
S17-J04 · 分布式事务:2PC / TCC / Saga / 本地消息表
适用读者:要跨库改数据、又不想"最终不一致"的人。
前置:S17-J03、S11-B06。
覆盖旧文:1561(181) 2641(186) 287(214) 892(75) = 656 点。
覆盖扩展:E-S17-007(四方案对比)、E-S17-008(本地消息表)。
上一篇:S17-J03 · 可靠投递:不丢、不重、有序
下一篇:S17-J05 · 分布式 ID。
1. 一句话结论
跨库"强一致"代价极高(2PC 锁长时间持有),工程上真正落地的是"最终一致":本地消息表(最常用)、TCC(强业务控制)、Saga(长流程)。
| 方案 | 一致性 | 实现成本 | 落地情况 |
|---|---|---|---|
| 2PC/XA | 强(同步阻塞) | 中 | 少(性能差) |
| TCC | 最终一致(业务补偿) | 高(要写三个方法) | 金融核心 |
| Saga | 最终一致(补偿链) | 中 | 长流程 |
| 本地消息表 | 最终一致 | 低 | 最常用 |
2. 为什么 2PC 不适合互联网业务
准备阶段:所有参与者锁住资源,等协调者
提交阶段:协调者决定提交/回滚
| 问题 | 说明 |
|---|---|
| 同步阻塞 | 准备阶段资源被锁(S11-B06 的长事务问题放大) |
| 协调者单点 | 协调者挂了参与者悬挂 |
| 性能 | 吞吐大幅下降 |
判据:"能接受几百毫秒到秒级的锁持有吗?" 不能 → 别用 2PC。
3. 四方案对比(E-S17-007)
| 维度 | 2PC | TCC | Saga | 本地消息表 |
|---|---|---|---|---|
| 一致性 | 强 | 最终 | 最终 | 最终 |
| 业务侵入 | 低 | 高(Try/Confirm/Cancel) | 中(补偿) | 低 |
| 隔离性 | 有 | 无(需自己防脏读) | 无 | 无 |
| 适用 | 短事务/内部 | 资金类 | 多步长流程 | 大多数场景 |
"TCC 的坑":没有隔离性——中间状态(Try 完成未 Confirm)会被其他事务读到,需要业务自己加状态位/锁。
4. 本地消息表:最实用的那一个(E-S17-008)
① 业务事务里:写业务表 + 写消息表(同一本地事务)
② 异步任务:读消息表 → 发 MQ → 标记已发
③ 消费端:幂等处理(J03)
| 优点 | 代价 |
|---|---|
| 只依赖本地事务 | 消息表要清理 |
| 简单、可靠 | 有秒级延迟 |
| 无需引入协调者 | 需要定时补偿 |
判据:"这一步能不能接受"秒级不一致"?" 能 → 本地消息表;不能 → 只能缩小范围(别跨库)。
5. 五个误区
| 误区 | 真相 |
|---|---|
| "2PC 能用在互联网高并发" | 锁持有时间不可接受 |
| "TCC 会自动隔离" | 无隔离性,要业务自己防 |
| "Saga 适合所有长流程" | 补偿逻辑要写对,否则数据错乱 |
| "分布式事务能解决一切" | 优先"不跨库"(拆错了) |
| "有了事务就不需要幂等" | 重试/重发仍需幂等 |
6. 自检
- 四方案的一致性与成本对比?
- 2PC 的两个硬伤?
- TCC 的隔离性问题怎么缓解?
- 本地消息表的三步?
- 为什么"优先不跨库"?
7. 下一篇
S17-J05 · 分布式 ID:雪花、号段与时钟回拨
事务讲完,下一篇讲"全局唯一 ID 怎么生成、为什么会重复"。
本篇属于系列《S17 · 分布式与消息队列》。旧文来源:A-1561/2641/287/892;扩展点 E-S17-007/008。
S17-J04 · 分布式事务:2PC / TCC / Saga / 本地消息表
https://www.clxhxhhr.top/posts/5427/ 评论
0 条
还没有评论,先写一条吧。