分布式事务学习总纲:零基础到资深专家的完整教学大纲
分布式 · 学习路线 · 总纲第 1 篇
本文是分布式事务领域的完整教学大纲:先定义「学成什么样算资深」,再把整个领域拆成可以逐个吃掉的小单元,后续系列文章按本大纲逐篇展开。
开头:为什么分布式事务特别需要一份大纲?
因为这个领域的知识点互相咬合得特别紧:
- 学 Seata AT 源码,一半的名词(undo log、快照、行锁)来自 MySQL 本地事务;
- 学 Seata 的 TC 集群高可用,绕不开 Raft 算法;
- 学可靠消息最终一致性,前置是 MQ 的投递语义;
- 评价这一切的标尺,是 CAP 和 BASE 定理。
没有路线图的学习是这样的:看 Seata 源码 → 看不懂 undo_log 生成 → 回去补 MySQL → 又被全局锁绕进去 → 转去看隔离级别 → 每个知识点都指向另一个知识点,学到哪都是黑洞,永远学不完一个完整的闭环。
这份大纲要做的事就一件:把这些互相咬合的知识点排成一条单向的线——每个单元只依赖前面的单元,学完一个,就扎实一个。这就是西蒙学习法在这个领域的落地方式。
一、学成什么样,才算「资深」?
先立靶子。学完本大纲,你应具备五项能力:
| # | 能力 | 具体表现 |
|---|---|---|
| 1 | 讲得清 | 能用 CAP / BASE 定理解释任何一个分布式事务方案的取舍 |
| 2 | 选得对 | 给定一个业务场景,能选出方案并说出为什么别的方案不合适 |
| 3 | 写得出 | Seata AT / TCC / Saga、可靠消息、最大努力通知,五种方案都能写出可运行代码 |
| 4 | 读得懂 | Seata AT 与 TCC 源码能追到「类名级别」的调用链,知道断点打在哪 |
| 5 | 修得了 | 空回滚、悬挂、消息丢失、全局锁冲突这类线上故障,能定位、能修复、能预防 |
注意「资深」的定义里没有「背会所有细节」——细节查文档就行,判断力才是资深的分水岭。
二、西蒙学习法在本领域的四个落法
西蒙学习法的核心:把领域拆碎成小单元,连续地、单点聚焦地逐个吃掉,每个单元立刻获得反馈。对应到本大纲:
- 拆碎:下面每个知识单元控制在 0.5 ~ 2 天内可完成,绝不出现「学 Seata」这种大块头,只有「追一遍 TM 开启全局事务的调用链」这种小块。
- 单点聚焦:一次只学一个单元。学全局锁的时候不要顺手去翻 Raft——忍住,它排在后面,到时候再看。
- 及时反馈:每个单元都配动手实验和验收标准。实验跑不通 = 没学会,不进入下一单元。
- 连续推进:每天 1.5 ~ 2 小时,每周 5 ~ 6 天,连续推进约 13 周。中断两周以上,从当前阶段的第一个单元重头来。
学习环境清单(开工前一次备齐)
| 工具 | 版本建议 | 用途 |
|---|---|---|
| JDK | 17 | 全部 Java 代码与 Seata 源码 |
| MySQL | 8.0 | 阶段 0 起全程使用 |
| Spring Boot | 3.x | 实战项目骨架 |
| Apache Seata | 2.6.0(2026-02 发布,坐标 org.apache.seata) | 阶段 3 主体 |
| Nacos | 最新稳定版 | Seata 注册/配置中心 |
| RocketMQ | 5.x | 事务消息 |
| Redis | 7+ | Gossip 实验(Cluster) |
| etcd | 最新稳定版 | Raft 实验 |
| Docker / IDEA | — | 环境搭建与源码调试 |
版本说明:Seata 已进入 Apache 孵化器(Apache Seata, incubating),Maven 坐标从旧版的
io.seata迁移为org.apache.seata,本大纲一律以org.apache.seata2.6.0 为准;查资料时注意老文章还在用io.seata。
三、知识全景图
六大阶段 + 一个毕业设计,总周期约 13 周:
| 阶段 | 主题 | 回答的核心问题 | 周期 |
|---|---|---|---|
| 0 | 地基:本地事务 | MySQL 和 Spring 到底怎么保证 ACID?它为什么管不到跨库? | 1 周 |
| 1 | 理论:CAP 与 BASE | 分布式系统为什么不能既要又要?方案的一致性强度怎么标? | 0.5 周 |
| 2 | 协议:2PC / 3PC / XA | 分布式事务的「原型机」长什么样?它烂在哪? | 1 周 |
| 3 | Seata 三部曲:AT / TCC / Saga | 工业级框架如何把 2PC 改造成能用的东西?(含源码) | 5 周 |
| 4 | 消息最终一致性:可靠消息 + 最大努力通知 | 不用协调器,靠消息能不能达成一致? | 1.5 周 |
| 5 | 共识算法:Paxos / Raft / Gossip | 多副本数据一致性怎么保证?TC 集群高可用靠什么? | 3 周 |
| 6 | 毕业:选型 + 综合实战 | 真实系统里怎么混搭这些方案? | 1 周 |
顺序设计的两个关键决定,先说透,免得学到一半怀疑路线:
- CAP/BASE 排在 Seata 之前:因为 Seata AT 的每一个设计决定(一阶段直接提交、全局锁、异步二阶段)都是一次 CAP 取舍。先有标尺,再看工程,看得懂「它为什么这么设计」。
- 共识算法排在最后:Paxos/Raft/Gossip 解决的是「多副本数据一致性」,不直接解决「跨服务业务一致性」——前者是后者的地基(TC 集群高可用靠 Raft 存储),但学 Seata 主线并不需要共识前置。先学业务事务,再学数据复制,最后回扣「Seata TC 为什么用 Raft」,每个算法都有工程锚点,不会学成纯数学。
四、阶段 0:地基——先把本地事务吃透(第 1 周)
为什么有这个阶段:分布式事务 = 本地事务 + 网络。Seata AT 源码里一半的概念(undo log、before/after 镜像、行锁)直接长在 InnoDB 的事务机制上。跳过这一步去读源码,每个断点都是天书。
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 0.1 ACID 与并发异常 | 脏读、不可重复读、幻读分别长什么样? | 两个 mysql 客户端开 RR 隔离级别,手工复现三种异常 | 每种异常能写出复现步骤 |
| 0.2 隔离级别与 MVCC | ReadView 和版本链怎么实现快照读? | 查 information_schema.innodb_trx,观察长事务 | 能画出一条记录的版本链 |
| 0.3 InnoDB 日志体系 | redo log、undo log、binlog 各管什么?内部两阶段提交是什么? | 崩溃恢复场景推演(写 redo 未写 binlog 会怎样) | 能画出 UPDATE 的完整落盘路径 |
| 0.4 Spring 事务 | @Transactional 传播行为有哪些?哪些场景会失效? | 写出「同类方法自调用导致事务失效」的最小复现 | 说出失效原因与 Spring 代理机制的关系 |
| 0.5 引出分布式 | 跨库、跨服务时,本地事务为什么失灵? | Spring Boot 双 DataSource 项目:库 A 扣款成功、库 B 加款抛异常,观察数据不一致 | 能画出「不一致窗口」发生在哪一步 |
阶段验收:脱稿画出一条 UPDATE 在 InnoDB 中的完整路径(SQL 解析 → 加行锁 → 写 undo → 写 redo → 写 binlog),并指出 undo log 将来在 Seata AT 里扮演什么角色。
五、阶段 1:理论——CAP 与 BASE(第 2 周前半)
为什么有这个阶段:后面每学一个方案,都要回答同一个问题——「你牺牲了 C 还是 A?换来了什么?」没有这两个定理,方案对比就只剩「别人都在用」。
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 1.1 分布式的物理现实 | 网络分区、部分失败、无全局时钟,各带来什么麻烦? | 推演:两机房专线断了,两边各自写入会怎样 | 能举出「部分失败」的三个具体例子 |
| 1.2 CAP 定理 | 为什么 P 不可放弃?C 和 A 怎么二选一? | 给 ZooKeeper、etcd、Eureka、Nacos、Redis、MySQL 主从做 CP/AP 站队,并说明理由 | 站队表能自圆其说 |
| 1.3 BASE 定理 | 基本可用、软状态、最终一致分别指什么?和 CAP 什么关系? | 用 BASE 解释「12306 查票显示余票 1 张,下单却说无票」 | 能说清 BASE = AP + 补偿机制 |
| 1.4 一致性谱系 | 强一致、线性一致、顺序一致、因果一致、最终一致,到底差在哪? | — | 能把 5 种一致性按强弱排序并各举一个系统 |
阶段验收:把 XA、Seata AT、TCC、可靠消息、最大努力通知、Saga 六个方案放进「一致性强度 × 侵入性」坐标系,并逐个说出取舍理由。(这题现在答不全没关系,它会在阶段 6 再考一次——两次答案的差距就是你进步的幅度。)
六、阶段 2:协议——2PC / 3PC / XA(第 2 周后半 ~ 第 3 周)
为什么有这个阶段:Seata AT 自称「改进型 2PC」,TCC 名字里的两个 C 就是两阶段。不知道原型机烂在哪,就理解不了改进的价值。
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 2.1 X/Open DTP 模型 | AP / TM / RM 三角色怎么分工? | — | 能说清 DTP 的 TM/RM 与 Seata 的 TC/TM/RM 命名对应关系 |
| 2.2 2PC 协议 | 投票、执行两阶段的时序?三大缺陷(同步阻塞、协调者单点、二阶段部分提交不一致)怎么发生? | 手画完整时序图,标出每个故障点 | 能逐个推演「协调者在 N 步宕机」后各参与者的状态 |
| 2.3 3PC 协议 | CanCommit / PreCommit / DoCommit 缓解了什么?又引入了什么? | 对比推演:网络分区下 2PC 与 3PC 的行为差异 | 说清 3PC 为什么仍是「缓解」而非「解决」 |
| 2.4 MySQL XA 实操 | XA 事务在 MySQL 里怎么跑? | 两个客户端手工执行 XA START/END/PREPARE/COMMIT 完成转账;PREPARE 后 kill 会话,用 XA RECOVER 观察悬挂事务 | 亲眼见过 in-flight 的 XA 事务长什么样 |
| 2.5 XA 的工程代价 | 为什么互联网公司基本不用 XA? | Spring Boot + Atomikos 双库 XA demo,与本地事务做简单压测对比 | 用「锁跨阶段持有」解释吞吐差距 |
阶段验收:一句话说清 XA 与 Seata AT 在「锁持有时间」上的本质区别(这是理解 AT 性能优势的钥匙)。
七、阶段 3:Seata 工程三部曲——AT / TCC / Saga(第 4 ~ 8 周)
主体阶段,占全程近一半时间。分四小节:AT 实战 → AT 源码 → TCC 实战+源码 → Saga。
3A. AT 实战(1.5 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 3A.1 三角色与生命周期 | TC / TM / RM 各干什么?XID 怎么串起全局事务? | 画生命周期五步图 | 能复述 TM 开启 → XID 传播 → RM 注册分支 → TM 提交 → TC 驱动分支的全过程 |
| 3A.2 部署 seata-server | TC 怎么跑起来?file / db 存储差在哪? | 用 db 存储 + Nacos 注册部署单机 TC,登录 console 观察全局事务列表 | 能在 console 里找到一次回滚事务的记录 |
| 3A.3 应用接入 | starter 怎么配?@GlobalTransactional 怎么用?undo_log 表是干嘛的? | 搭「订单-库存-账户」三库(或三服务)项目,全部走 Nacos | 下游抛异常时全局回滚成功,三库数据一致 |
| 3A.4 两阶段拆解 | 一阶段做了哪四件事(业务 SQL、查镜像、存 undo、拿全局锁)?二阶段为什么能异步? | 回滚场景下观察 undo_log 表内容变化 | 能写出一条 undo_log 的 before/after 镜像 JSON |
| 3A.5 隔离性 | 全局锁怎么防脏写?读隔离为什么要 @GlobalLock + select for update? | 绕过框架直接改下游库,观察全局锁拦截报错 | 说清 AT 默认读未提交的原因与补救 |
3B. AT 源码(1.5 周)——重点攻坚
源码阅读方法:先在实战项目跑通回滚场景,再按「一条全局事务的生命周期」打断点追,不要按包结构从头翻。
| 单元 | 回答的核心问题 | 断点路线 | 吃透的标准 |
|---|---|---|---|
| 3B.1 TM 侧链路 | @GlobalTransactional 是谁拦截的?begin/commit 走到哪? | GlobalTransactionalInterceptor → TransactionalTemplate → DefaultGlobalTransaction → TM 向 TC 发 GlobalBeginRequest | 能脱稿写出 TM 侧类名级调用链 |
| 3B.2 XID 传播 | XID 怎么跨 RPC / HTTP 传下去? | RootContext.bind → 各 RPC 框架的 filter 链 | 说清 XID 放在哪个上下文、怎么恢复 |
| 3B.3 RM 一阶段 | 数据源代理怎么拦截 SQL?镜像怎么生成?全局锁怎么申请? | DataSourceProxy → ConnectionProxy → ExecuteTemplate → SQL 解析器(Select/Update 识别器)→ 生成 before/after 镜像 → UndoLogManager 写 undo_log → 分支注册 + 全局锁 | 能讲出一阶段「业务 SQL 与 undo 同本地事务提交」的原理(这是 AT 无侵入的关键) |
| 3B.4 TC 侧 | 全局会话/分支会话怎么维护?四种存储模式(file/db/redis/raft)差在哪? | DefaultCoordinator → DefaultCore(begin / branchRegister / globalCommit / globalRollback)→ GlobalSession / BranchSession → SessionHolder | 说清 TC 重启后事务不丢的条件 |
| 3B.5 二阶段 | commit 为什么异步删 undo 就行?rollback 怎么反向补偿?超时谁管? | commit 链路:异步批量删 undo_log;rollback 链路:BranchRollbackRequest → 用 before 镜像反向补偿;timeoutCheck 定时检测 | 能画出提交、回滚两条完整时序(含失败重试) |
加分实验:实现一个 Seata SPI 扩展点(如事务事件监听 / 自定义 Metrics),把全局事务审计日志打到自己的表里——证明你真的摸到了扩展体系,而不只是读了一遍。
3C. TCC 实战与源码(1 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 3C.1 TCC 三段语义 | Try 预留 / Confirm 确认 / Cancel 释放,各自业务上怎么写?与 AT 对比(侵入 vs 无侵入、性能 vs 开发量) | 库存 TCC:try 冻结库存、confirm 扣减冻结、cancel 解冻 | 三个方法的数据表设计能画出来(可用同一张表加冻结字段) |
| 3C.2 三大问题 | 空回滚、悬挂、幂等各自的触发时序是什么? | 先不开 fence,人为构造 Cancel 先于 Try 到达,复现空回滚 | 能画出三个问题各自的异常时序图 |
| 3C.3 Fence 机制 | useTCCFence 的 fence 表怎么一表防三害? | 开启 fence,重复上面实验,观察被拦截;查 tcc_fence_log 表 | 说清 fence 记录状态(初始化 / 已提交 / 已回滚 / 悬挂)分别挡住哪个问题 |
| 3C.4 TCC 源码 | TCC 切面怎么把一个接口拆成两阶段? | @TwoPhaseBusinessAction 解析 → TccActionInterceptor → Try 提交后注册分支 → 二阶段回调 Confirm/Cancel 方法;TransactionFenceManager 初始化 fence | 能对比 AT 与 TCC 在「分支注册」这一步的异同 |
3D. Saga(1 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 3D.1 Saga 理论 | 1987 年论文里的 LLT 怎么拆成 T1..Tn + 补偿 C1..Cn?补偿和回滚的区别? | 读原论文前两节(不长) | 说清「补偿是业务上的反向操作,不是数据库回滚」 |
| 3D.2 编排 vs 协同 | 状态机编排和事件协同各适合什么? | 画两种风格的订单流程图 | 说清 Seata Saga 走的是哪条路线(编排) |
| 3D.3 Seata Saga 状态机 | JSON DSL 怎么写?补偿、重试、向前恢复怎么配? | 用状态机跑「下单-扣款-送积分-发券」,扣款失败触发逆向补偿 | 设计器里能看懂一张状态机图的每个节点 |
| 3D.4 适用场景 | 什么时候非 Saga 不可? | — | 三问选型:能否预留资源?事务多长?参与方可控吗? |
阶段 3 总验收:给定「秒杀扣库存 + 生成订单 + 送积分」,分别用 AT、TCC、Saga 各实现一遍,写一篇对比笔记(代码量、侵入性、一致性强度、性能直觉四个维度)。
八、阶段 4:消息最终一致性——可靠消息 + 最大努力通知(第 9 ~ 10 周)
为什么有这个阶段:Seata 是同步强一致系;高并发场景更常用的是异步最终一致——两条技术栈都要会,选型时才有得选。
4A. 可靠消息最终一致性(1 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 4A.1 问题定义 | 「事务成功但消息丢」和「消息发成功但事务回滚」两种不一致,分别怎么发生? | — | 能画出两种时序图 |
| 4A.2 本地消息表 | 业务表和 outbox 表同库同事务 + 定时扫表补偿,怎么保证不丢? | 先手写本地消息表版「注册成功-发优惠券」:业务与消息插入同事务,后台线程扫描补发 | 说清为什么「同库同事务」是灵魂 |
| 4A.3 RocketMQ 事务消息 | half message、本地事务、commit/rollback、回查,四个环节怎么咬合? | 切换到 RocketMQ 5.x 事务消息版;本地事务里 sleep 模拟超时,观察 broker 回查 | 画出全时序图,标出回查兜底的位置 |
| 4A.4 消费端幂等 | 消息重复投递怎么防? | 消费端用去重表(消息 key 唯一索引)实现幂等 | 说清「至少一次投递 + 幂等消费 = 恰好一次效果」 |
4B. 最大努力通知(0.5 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 4B.1 与可靠消息的分野 | 为什么跨企业通知(如支付回调)不追求强一致,靠「我尽力通知 + 你主动查证」? | 模拟支付结果通知第三方:失败后按衰减间隔重试(如 1m/5m/10m/30m/1h),并提供查证接口 | 说清通知方衰减重试 + 被通知方查证兜底 + 对账文件三层防线 |
| 4B.2 方案对比 | 可靠消息 vs 最大努力通知,差在哪? | — | 一张表对比:消息方向、是否依赖 MQ、一致性要求、典型场景 |
阶段 4 总验收:把「注册-发券」分别用本地消息表和事务消息实现后,kill 各种进程(业务进程、MQ、消费方)各验证一次恢复能力,记录哪些环节断了也能最终一致。
九、阶段 5:共识算法——Paxos / Raft / Gossip(第 11 ~ 13 周)
深水区,也是「资深」和「会用」的分水岭。保持节奏:每个算法先懂「它解决什么问题」,再抠机制,最后必须落到工程锚点上。
5.0 复制与 Quorum 基础(2 天)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 5.0.1 复制模式 | 主从复制、多主、无主各怎么工作? | — | 说清「为什么多数派写入能容忍少数派故障」 |
| 5.0.2 Quorum (NWR) | W + R > N 保证了什么? | 推演:N=3, W=2, R=1 时读到旧数据的场景 | 能用 NWR 解释 Dynamo 系存储的取舍 |
5.1 Paxos(1 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 5.1.1 Basic Paxos | Proposer / Acceptor / Learner 怎么用 prepare + accept 两阶段对一个值达成一致? | 纸面推演:两个 Proposer 交错提案的活锁场景 | 能手画完整消息时序,含被拒绝后的重新提案 |
| 5.1.2 Multi-Paxos | 选出 leader 后为什么可以省掉 prepare?instance 和日志怎么组织? | — | 说清 Basic Paxos「一次只定一个值」和工程上「定一串日志」的鸿沟怎么填 |
读法:Lamport 的 Paxos Made Simple(2001)只有十几页,先读它,别从 The Part-Time Parliament 入手。
5.2 Raft(1 周)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 5.2.1 分解思想 | Raft 把共识拆成哪三个子问题?为什么说它是「为可理解性设计」的? | — | 能复述三子问题与它们各自的约束 |
| 5.2.2 Leader 选举 | 任期、随机超时、多数派投票怎么防止脑裂? | raft.github.io 可视化页面强制触发选举,观察任期变化 | 能推演「旧 leader 复活后发现已有新 leader」的处理 |
| 5.2.3 日志复制 | AppendEntries 的匹配规则?什么条件下日志算提交? | 可视化页面制造日志不一致,观察新 leader 如何覆盖 | 说清「选举限制」(只有拥有最新日志者可当选)防住什么 |
| 5.2.4 安全性与成员变更 | 为什么提交规则要检查 CurrentTerm?联合共识是什么? | — | 能举出「坏例子」:旧任期日志被误提交的后果 |
| 5.2.5 工程锚点:etcd | 生产级 Raft 长什么样? | 本地起 3 节点 etcd 集群,etcdctl endpoint status 看 leader;kill leader 观察自动选举与写入恢复 | 亲手见过一次选主 |
| 5.2.6 工程锚点:Seata TC 的 Raft 存储 | seata-server 的 raft 存储模式(2.0+ 引入)怎么让 TC 自己高可用? | 3 节点 raft 模式 seata-server,kill TC leader,验证全局事务被新 leader 接管 | 回扣主线:讲清「TC 为什么用 Raft 而不是主从复制」 |
| 5.2.7 ZAB 一眼对照 | ZooKeeper 的 ZAB 和 Raft 像在哪、差在哪? | — | 一段话说清即可,不深挖 |
5.3 Gossip(3 ~ 4 天)
| 单元 | 回答的核心问题 | 动手实验 | 吃透的标准 |
|---|---|---|---|
| 5.3.1 传染病模型 | 反熵(push / pull / push-pull)和谣言传播各怎么收敛?为什么是 O(log n)? | 纸面模拟:16 节点 push-pull 传播轮次 | 说清反熵保最终一致、谣言传播保低开销的分工 |
| 5.3.2 故障检测 | SWIM 怎么做到「最终怀疑」又不误杀? | — | 说清间接探测的作用 |
| 5.3.3 工程锚点:Redis Cluster | 节点发现、槽迁移、故障转移怎么靠 gossip? | 6 节点(3 主 3 从)Redis Cluster:CLUSTER MEET 后观察节点表收敛;kill 一个主,观察故障转移时间线 | 说清「为什么元数据类系统爱用 Gossip(AP),而事务存储用 Raft(CP)」 |
阶段 5 总验收:三道口述题——① Basic Paxos 两阶段各防住什么;② Raft 一个日志条目从客户端到提交的完整旅程;③ 为什么 Seata TC 用 Raft、Redis Cluster 用 Gossip、而两者都是对的。
十、阶段 6:毕业——选型 + 综合实战(第 14 周)
6.1 选型决策树(背下来)
业务需要跨服务一致性?
├─ 必须强一致、参与者是自己人?
│ ├─ 不想改业务代码、性能要求不高 → Seata AT
│ ├─ 高并发、愿意改代码做资源预留 → Seata TCC
│ └─ 数据库都支持 XA、并发低 → XA(2PC)
├─ 长事务 / 参与方不可控(第三方、遗留系统)→ Saga
├─ 可以异步、允许秒级延迟 → 可靠消息最终一致性
└─ 只是「通知对方」、对方有查证能力 → 最大努力通知6.2 综合实战(毕业设计)
设计并实现一个电商交易链路,强制混搭五种方案:
| 环节 | 要求方案 | 考点 |
|---|---|---|
| 订单创建 + 库存扣减 | TCC(或 AT) | 资源预留、防超卖 |
| 支付成功 → 积分/优惠券 | 可靠消息 | 事务消息 + 幂等消费 |
| 物流状态通知合作方 | 最大努力通知 | 衰减重试 + 查证接口 |
| 退款流程(涉及第三方支付渠道) | Saga | 补偿设计 |
| 全链路 | 各方案失败演练 | 每个环节人为断一次,验证恢复 |
交付物:架构图一张、设计文档一篇(每个环节的选型理由,必须用 CAP/BASE 说理)、可运行代码、故障演练记录。
6.3 资深自检 20 问(节选)
- AT 一阶段为什么敢直接提交本地事务?回滚靠什么保证?
- undo_log 的 before 镜像和 after 镜像分别用在哪一步?
- 全局锁和 InnoDB 行锁是什么关系?会不会互相死锁?
- TCC 的 fence 表一条记录能挡住空回滚和悬挂两个问题,怎么做到的?
- 为什么 RocketMQ 事务消息需要回查,而本地消息表不需要?
- 最大努力通知的通知方和被通知方,谁持有一致性的最终责任?
- Saga 的补偿失败了怎么办(向前恢复 vs 向后恢复)?
- 2PC 协调者在第二阶段宕机,参与者会处在什么状态?3PC 改善了什么?
- CAP 里的 C 和数据库 ACID 里的 C 是一回事吗?
- Raft 的选举限制为什么能保证已提交日志不丢?
(完整 20 问在毕业设计时自测,答不出哪个,回对应阶段补哪个。)
十一、总时间线
| 周 | 内容 |
|---|---|
| 1 | 阶段 0:本地事务地基 |
| 2 | 阶段 1:CAP/BASE + 阶段 2 开始:DTP、2PC |
| 3 | 阶段 2 续:3PC、XA 实操 |
| 4 ~ 5 | 阶段 3A:Seata AT 实战 |
| 5 ~ 6 | 阶段 3B:AT 源码攻坚 |
| 7 | 阶段 3C:TCC 实战与源码 |
| 8 | 阶段 3D:Saga |
| 9 | 阶段 4A:可靠消息 |
| 10 | 阶段 4B:最大努力通知 + 阶段 5.0 Quorum |
| 11 | 阶段 5.1:Paxos |
| 12 | 阶段 5.2:Raft(含 etcd / Seata TC 实操) |
| 13 | 阶段 5.3:Gossip |
| 14 | 阶段 6:毕业设计 |
每天 1.5 ~ 2 小时。进度可以慢,顺序不要乱:每个阶段的验收没过,不进下一阶段。
十二、参考资料(均已核验为当前版本)
官方文档
- Apache Seata 官网与文档(孵化中项目,本文基准 2.6.0,2026-02 发布;Maven 坐标
org.apache.seata) - apache/incubator-seata GitHub 仓库(源码与各模式文档)
- RocketMQ 5.x 官方文档 · 事务消息(half message 与回查机制)
- etcd 官方文档(Raft 的生产级实现)
- Redis 官方文档 · Cluster 规范(Gossip 协议与故障转移)
论文(按阅读顺序)
- Garcia-Molina & Salem, Sagas, SIGMOD 1987 —— Saga 的源头,只需读前两节
- Brewer, CAP Twelve Years Later, IEEE Computer 2012 —— 比原 keynote 更准确,先读这篇再看 2000 讲稿
- Lamport, Paxos Made Simple, 2001 —— 十几页,Paxos 首选读物
- Ongaro & Ousterhout, In Search of an Understandable Consensus Algorithm (Raft), USENIX ATC 2014 —— 配 raft.github.io 可视化 阅读
- DeCandia et al., Dynamo, SOSP 2007 —— NWR 与 Gossip 的工程源头
书
- 《数据密集型应用系统设计》(DDIA):第 5 章(复制)、第 7 章(事务)、第 9 章(一致性与共识)——本大纲的理论部分与它互为印证,读完大纲再读它,吸收率完全不同。
结语:一条线,走到底
这份大纲的本质是把一个互相咬合的知识网络压平成一条链:
本地事务 → 理论标尺 → 协议原型 → 工程框架(实战 + 源码)→ 异步方案 → 共识地基 → 混合选型
每个环节只有一个入口——前一个环节。从阶段 0 第一个实验开始,走完这条线,你就是能讲、能选、能写、能读、能修的资深工程师。
系列占位文档已按本大纲建好:8 个模块共 49 篇,每篇列出「要解决的问题、知识点清单、动手实验、验收标准」,完成一篇就去掉一篇的「占位待学」标记。完整索引见专栏目录(侧边栏按学习顺序排列)。
下一篇,从阶段 0 的第一个实验开始:《ACID 与并发异常:亲手复现脏读、不可重复读、幻读》。