4. 分布式事务模式:TCC、Saga、可靠消息、最大努力通知

在分布式系统中,传统数据库的 ACID 事务无法跨服务边界生效。本章深入剖析四种主流分布式事务模式,帮助你在事件风暴画布中为每个聚合边界选择最合适的补偿或协调策略。

4.1 四种模式总览

模式 核心思想 一致性类型 典型场景
TCC Try-Confirm / Cancel 两阶段反向补偿 强一致性(短锁) 库存扣减、账户扣款
Saga 长事务拆为本地子事务 + 补偿子事务 最终一致性 订单创建、旅行预订
可靠消息 本地消息表 + 异步投递 + 回调确认 最终一致性 积分发放、异步通知
最大努力通知 定时重试 + 幂等 + 人工兜底 弱一致性 支付回调、第三方推送
选型原则: 业务对一致性敏感度越高,越靠近 TCC;对可用性要求极高且允许短暂不一致,优先考虑 Saga 或可靠消息;外部系统不可控时,使用最大努力通知。

4.2 TCC 模式

TCC(Try-Confirm-Cancel)将每个分布式操作拆分为三个阶段:Try 预留资源,Confirm 确认执行,Cancel 回滚释放。所有参与者必须实现这三个接口。

TCC 两阶段协调流程 事务协调器 服务 A(Try) 服务 B(Try) 服务 C(Try) Confirm / Cancel Confirm / Cancel Confirm / Cancel Try 阶段预留资源 → 全部成功则 Confirm,任一失败则对所有参与者执行 Cancel
实现要点:
  • Try 阶段必须预留足够资源,不能直接提交业务数据。
  • Confirm 和 Cancel 必须幂等,协调器会重试直到成功。
  • Cancel 要能完全回滚 Try 的预留动作,不留脏数据。

4.3 Saga 模式

Saga 将一个长事务拆分为多个本地子事务,每个子事务对应一个补偿子事务。执行时按顺序正向提交;若某步失败,则反向依次触发补偿。

Saga 正向执行与反向补偿 T1 创建订单 T2 扣库存 T3 扣余额 T4 发积分 C4 撤销积分 C3 回退余额 C2 恢复库存 C1 取消订单 T3 扣余额失败 → 触发 C4 → C3 → C2 → C1 反向补偿,恢复至初始状态 补偿子事务必须幂等,且能正确处理部分失败场景
注意: Saga 没有隔离性,中间状态对外可见。业务上需通过“幂等 + 补偿”保证最终一致,必要时引入语义锁或防悬挂机制。

4.4 可靠消息模式

可靠消息模式通过“本地消息表 + 异步投递 + 回调确认”保证业务操作与消息发送的原子性。核心流程如下:

  1. 业务操作:在本地事务中同时写入业务数据和消息记录(状态为“待投递”)。
  2. 定时扫描:独立任务轮询消息表,将待投递消息发送到 MQ。
  3. 消费确认:消费者处理成功后回调生产者,更新消息状态为“已消费”。
  4. 重试与清理:超过重试次数的消息转入死信队列或人工处理。
-- 本地消息表结构示例
CREATE TABLE reliable_message (
    id          BIGINT PRIMARY KEY AUTO_INCREMENT,
    business_id VARCHAR(64)  NOT NULL COMMENT '业务主键',
    topic       VARCHAR(128) NOT NULL,
    payload     TEXT         NOT NULL,
    status      TINYINT      NOT NULL DEFAULT 0 COMMENT '0:待投递 1:已投递 2:已消费 3:死亡',
    retry_count INT          NOT NULL DEFAULT 0,
    create_time DATETIME     NOT NULL,
    update_time DATETIME     NOT NULL,
    INDEX idx_status_retry (status, retry_count)
);
关键设计: 消费者必须实现幂等消费(通过 business_id 去重),防止重复投递导致数据不一致。

4.5 最大努力通知模式

最大努力通知适用于与外部系统(如第三方支付、短信网关)的交互,发起方尽最大努力将结果通知到接收方,但不保证 100% 送达。核心机制:

  • 定时重试:按指数退避策略重试(如 1s、2s、4s、8s…),达到最大次数后停止。
  • 幂等接收:接收方通过唯一通知 ID 去重,避免重复处理。
  • 人工兜底:提供查询接口或后台页面,供运营人员手动对账和补偿。
对比维度 可靠消息 最大努力通知
投递保证 至少一次(At-Least-Once) 尽最大努力(Best-Effort)
重试策略 持久化 + 无限重试直到成功 有限次重试 + 人工介入
适用场景 内部服务间异步协调 外部不可控系统对接
一致性等级 最终一致(可保证) 最终一致(不保证)

4.6 事件风暴画布中的模式映射

在事件风暴工作坊中,识别出聚合、命令、事件和策略后,按以下规则映射分布式事务模式:

  • 强一致边界(如库存、账户):使用 TCC,在画布上标记为 【TCC】 并注明 Try/Confirm/Cancel 事件。
  • 长流程编排(如订单 → 支付 → 发货):使用 Saga,在画布上绘制正向事件流和补偿事件流。
  • 异步解耦(如订单创建后发积分):使用可靠消息,在画布上添加“消息表”聚合和“定时投递”策略。
  • 外部回调(如支付网关通知):使用最大努力通知,在画布上标注“重试策略”和“人工对账”边界。
实战建议: 一个复杂业务通常混合使用多种模式。例如:订单主流程用 Saga,库存扣减用 TCC,积分发放用可靠消息,支付回调用最大努力通知。在事件风暴画布上为每个聚合边界独立标注模式,避免一刀切。