软件技术 · 知识点深化 · 分布式系统
分布式事务:2PC、TCC、本地消息表、最大努力通知
单体时代一个数据库事务搞定一切,微服务拆成多个库后,本地事务跨库就不灵了。分布式事务要解决的是:扣库存、减余额、发优惠券三个操作要么都成功要么都失败。这一页讲透 2PC、TCC、本地消息表、Saga 四种方案的取舍。
① 怎么学(4 步走,约 75 分钟)
先建立直觉再抠细节,按这四步走最稳:
1看图建立直觉(10 分钟)
读②③:先在脑子里画出本课核心结构图。
2记完整体系(15 分钟)
读④:把对比表和公式看懂,不要急着背。
3跟例题走一遍(20 分钟)
精读⑤:看三个例题怎么用知识点解题。
4刷题纠错(剩余时间)
做⑦⑩,错题回⑥诊断。
本课小目标学完你要能:① 说清为什么需要分布式事务;② 对比 2PC/TCC/本地消息表;③ 选择合适方案;④ 解释最终一致性。
② 一图看懂:分布式事务方案全景
读法:中心是本课主题,四条分支展开核心维度,下方是典型应用与高频易错点。
③ 本质直觉:分布式事务就是"多人合伙结账"
你在饭店请客:你点单、朋友 A 点酒、朋友 B 点甜品。最后结账时要保证三个人要么都付得起,要么这单就取消。
2PC(两阶段提交):服务员先问所有人"能付吗?"(准备阶段),都回答"能"再喊"一起付"(提交阶段)。问题:有人犹豫时其他人干等(同步阻塞),服务员中途晕倒大家都卡住。
TCC:每人先做预留动作(Try:冻结余额),确认没问题再真正扣(Confirm),出问题就解冻(Cancel)。业务层面自己实现三个接口。
本地消息表:先把消息存在本地库(和业务操作同事务),再异步通知下游。即使下游暂时失败,重试直到成功。接受短暂不一致,最终一致。
Saga:长事务拆成一串本地事务,每步有对应的补偿操作。前面成功后面失败就反向补偿。
CAP 取舍跨网络的分布式事务不可能强一致(C)+高可用(A)。大多数业务接受最终一致,用本地消息表+重试+对账。
④ 完整知识体系
四种方案对比
| 方案 | 一致性 | 性能 |
| 2PC/XA | 强一致 | 差,同步阻塞 | 传统DB跨库 |
| TCC | 最终一致 | 较好,业务侵入大 | 资金/账户 |
| 本地消息表 | 最终一致 | 好,简单可靠 | 大多数业务 |
| Saga | 最终一致 | 好,补偿复杂 | 长流程业务 |
TCC 三阶段Try 资源预留 -> Confirm 正式提交 -> Cancel 回滚释放
本地消息表业务操作 + 写消息表 在同一本地事务 -> 异步投递 MQ -> 下游消费
为什么 2PC 不实用
同步阻塞:参与者锁定资源等待协调者;单点故障:协调者挂了参与者永久阻塞;数据可能不一致:Commit 阶段部分参与者没收到。
本地消息表方案
1. 下单和写消息表在同一本地事务;2. 后台任务扫消息表,投递到 MQ;3. 下游消费成功后回执;4. 失败重试,超过次数人工对账。
⑤ 应用场景与例题
例1 下单扣库存减余额,选什么方案?
电商场景,可用性优先。
本地消息表。下单和写消息同事务,异步通知库存和账户服务。容忍几秒不一致,失败重试。不要用 2PC,同步阻塞把订单服务拖垮。
例2 银行转账,选什么方案?
100 元从 A 到 B,不能错。
TCC。Try 阶段冻结 A 账户 100 元,Confirm 时扣 A 加 B,Cancel 时解冻。资金场景对一致性要求高,业务值得侵入。
例3 2PC 协调者挂了会怎样?
参与者一直阻塞。
准备阶段后协调者宕机,参与者锁定资源等待 Commit/Rollback,永远等不到。这是 2PC 的致命缺陷。
做题心法能最终一致就别强一致,本地消息表是大多数业务的首选。
⑥ 高频错误诊断(4 条)
错误1:跨服务用 @Transactional本地事务只对本库生效,跨服务无效。
错误2:消息投递和业务分开提交业务成功消息没发出去,数据不一致。必须同事务写消息表。
错误3:2PC 当万能方案同步阻塞+单点故障,高并发场景不可用。
错误4:TCC 不做幂等Confirm/Cancel 可能被重复调用,必须幂等设计。
⑦ 考点真题演练(5 题)
考点分布
| 考法 | 出题形式 | 应对 |
| 方案对比 | 问哪种性能好 | 本地消息表 |
| TCC | 问三阶段 | Try/Confirm/Cancel |
| 2PC | 问缺点 | 同步阻塞+单点 |
| 消息表 | 问和业务怎么同事务 | 本地事务 |
真题basic1. 跨服务事务推荐哪种方案?
真题mid2. TCC 的三个阶段是?
真题mid3. 本地消息表方案中,消息表和业务操作?
真题hard4. 2PC 的主要缺点不包括?
真题hard5. Saga 模式适合什么场景?
⑧ 必背知识点卡
问题:本地事务跨库失效
2PC:准备+提交,同步阻塞 不实用
TCC:Try 预留 Confirm 提交 Cancel 回滚 资金场景
消息表:业务+消息同事务,异步投递 最常用
Saga:长事务拆步,失败反向补偿
一致性:大多数业务接受最终一致
幂等:重试必须幂等
⑨ 动手输出:设计下单扣库存的分布式事务
场景:下单要扣库存、减余额、发优惠券,怎么保证一致?
① 选型:本地消息表+最终一致。
② 订单服务:创建订单和写消息表在同一本地事务提交。
③ 异步:扫表任务投递到 MQ,库存/账户服务消费。
④ 失败:消费失败重试,超过次数告警人工对账。
⑤ 兜底:每天跑对账任务,发现不一致自动补偿。
口述思路接受短暂不一致,用重试+对账换可用性和性能。
⑩ 分层练习(基础 + 中档 + 拔高)
▍基础 6 题
基础1为什么微服务需要分布式事务?
本地事务不能跨库跨服务。
基础3TCC 全称?
Try-Confirm-Cancel。
基础4本地消息表和业务在同一什么里?
本地事务。
基础5Saga 失败怎么办?
反向补偿前面步骤。
基础6分布式事务追求强一致还是最终一致?
大多数场景最终一致。
▍中档 5 题
中档1为什么 2PC 性能差?
同步阻塞,参与者锁资源等协调者。
中档2TCC 为什么业务侵入大?
每个服务要实现 Try/Confirm/Cancel 三个接口。
中档3本地消息表怎么保证消息不丢?
业务和消息同事务,投递失败重试。
中档4为什么要幂等?
网络重试会导致下游重复执行。
中档5最终一致的延迟能接受吗?
电商场景几秒内可接受,资金场景不行。
▍拔高 5 题
拔高12PC 协调者宕机会怎样?
参与者永久阻塞等待。
拔高2TCC 的 Try 阶段做什么?
预留资源(冻结金额/库存),不真正扣减。
拔高3消息表怎么防止重复投递?
消费端幂等,消息带唯一 ID。
拔高4Saga 和 TCC 区别?
TCC 是两阶段预留;Saga 是直接执行+补偿。
拔高5Seata AT 模式原理?
自动生成反向 SQL 回滚,无业务侵入。
⑪ 记忆口诀 + 7 天复习计划
三句口诀① 跨库事务本地管不了,四种方案选合适。② 2PC 阻塞别用,TCC 资金才上。③ 消息表最通用,业务消息同事务。
| 天 | 任务 | 自检 |
| 第 1 天 | 读②③,画四方案对比图 | 能分类 |
| 第 2 天 | 背方案表 + 基础 6 题 | 特点记住 |
| 第 3 天 | 做中档 5 题,写消息表流程 | 步骤对 |
| 第 4 天 | 做拔高 5 题,对比 TCC/Saga | 区别说清 |
| 第 5 天 | 做⑦真题 5 题 | 限时每题 2 分钟 |
| 第 6-7 天 | 合书口述为什么不用 2PC | 不看资料 |
← 返回软件技术总览