Week 3 · Chapter 4 · 分布式事务

复习难度:⭐⭐⭐⭐⭐ | 预计时长:4-5小时 | 重点程度:高


核心问题

跨多个服务 / 数据库节点,如何保证"要么全成功,要么全失败"?
单机事务 → ACID
分布式事务 → CAP 定理 + BASE 理论

1. CAP 定理

C (Consistency):  所有节点数据一致
A (Availability):  每个请求都有响应
P (Partition Tolerance): 分区容错(网络分区不可避免)

三选二:
  CA (不可能):单机 DB
  CP (分布式DB):优先一致,放弃可用(如 ZK / etcd / Consul)
  AP (DNS / Eureka):优先可用,放弃强一致

分布式系统一定是 CP 或 AP,没有CA。


2. BASE 理论

Basically Available:软状态,允许中间状态
Soft state:数据副本可能不一致
Eventually consistent:最终一致

BASE 是 CAP 中 AP 的实践落地:强一致做不到,就追求最终一致。


3. 两阶段提交(2PC)

角色:协调者(Coordinator)+ 参与者(Participant)

阶段1(Prepare):
  协调者问所有参与者:"能提交吗?"
  参与者预执行(锁定资源),写 redo/undo log
  参与者回答:"可以" 或 "不可以"

阶段2(Commit/Rollback):
  全部回答"可以" → 协调者发 Commit → 所有人提交
  任何一个"不可以" → 协调者发 Rollback → 所有人回滚

缺点: - 协调者单点故障(协调者挂了,参与者卡死) - 同步阻塞(Prepare 阶段锁定资源直到 Commit/Rollback) - 数据不一致(Commit 阶段部分成功部分失败)


4. TCC(Try-Confirm-Cancel)

Try:预留资源(冻结/预扣)
Confirm:确认执行(真正扣减)
Cancel:取消回滚(释放冻结)

和2PC的区别:
  - 2PC 是数据库层面的锁定
  - TCC 是业务层面的资源预留
  - TCC 更灵活,但代码侵入性高

你审批平台里用了 TCC 吗?

可以提到:审批单状态机 + 补偿机制,本质上是简化的 TCC 模式。


5. Saga 模式

每个服务执行本地事务,然后发布事件
如果某步骤失败,按反向顺序执行补偿事务

适用场景:长事务(跨十几个服务的业务流程)

两种补偿策略: 1. 顺序补偿(Choreography):服务间通过事件链协调 2. 中央协调(Orchestration):一个 Saga Orchestrator 统一发号施令


6. 本地消息表(最实用)

核心思路:把分布式事务拆成"同步本地事务" + "异步消息"

1. 在本地库建一张消息表
2. 业务操作和消息插入在同一事务里
3. 后台任务扫描消息表,发送 MQ
4. 消费端幂等处理
5. 定期补偿失败的消息
-- 消息表结构
CREATE TABLE outbox (
    id BIGINT PRIMARY KEY,
    event_type VARCHAR(64),
    payload JSON,
    status TINYINT DEFAULT 0,  -- 0待发送 1已发送 2已确认
    retry_count INT DEFAULT 0,
    created_at DATETIME,
    updated_at DATETIME
);

这种方案在你的游戏活动系统奖励发放中可以用到:

活动参与 → 发放奖励 → 本地事务写 order + 消息表 → MQ通知 → 异步发货


高频面试题

Q1:如何选择分布式事务方案?

① 强一致性要求(银行/支付)→ 2PC/XA ② 业务可接受最终一致 → 本地消息表 / Saga ③ 高并发场景 → 本地消息表 + MQ,避免2PC性能差 ④ 跨服务调用且需要补偿 → TCC

Q2:分布式事务和一致性区别?

分布式事务解决的是"如何让多个节点同时成功或失败" 一致性是结果状态,分布式事务是达成一致性的手段

Q3:Saga 和 TCC 的区别?

TCC 强调资源预留(Try阶段冻结资源),需要业务提供 Confirm/Cancel 回调 Saga 强调正向执行(每个服务直接做),失败后执行补偿 TCC 更强但侵入性更大,Saga 更轻但一致性保证较弱