3. 分布式事务理论:CAP定理、BASE理论、最终一致性、分布式事务常见解决方案

在分布式系统中,数据一致性与系统可用性、分区容错性之间存在根本性的权衡。本章将系统梳理分布式事务的核心理论基石,并对比主流实现方案,为后续在事件风暴画布中设计事务边界提供理论依据。

3.1 CAP定理:分布式系统的“不可能三角”

CAP定理由Eric Brewer于2000年提出,是分布式系统设计的根本约束。它指出:一个分布式系统最多只能同时满足以下三个特性中的两个:

特性 全称 含义 典型场景
C Consistency(一致性) 所有节点在同一时刻看到相同的数据副本 银行转账、库存扣减
A Availability(可用性) 每个请求都能获得非错误的响应(不保证数据最新) CDN缓存、商品详情页
P Partition Tolerance(分区容错性) 系统在网络分区(节点间通信中断)时仍能正常运行 跨机房部署、微服务网络抖动
关键认知: 在分布式系统中,网络分区是必然发生的,因此P是必选项。实际设计是在CP(强一致+分区容忍)与AP(高可用+分区容忍)之间做选择。

下图展示了CAP定理的三角关系以及常见的系统选型路径:

CAP 定理:分布式系统选型三角 C 一致性 A 可用性 P 分区容忍 CP 系统 ZooKeeper / Etcd AP 系统 Eureka / Cassandra CA 系统(单机)

3.2 BASE理论:对CAP的务实妥协

BASE理论是eBay架构师Dan Pritchett提出的,是对CAP中AP路线的实践总结。它由三个要素构成:

  • BA(Basically Available)基本可用: 系统允许出现响应延迟或降级,但最终必须返回结果。
  • S(Soft State)软状态: 允许系统中间状态存在,不要求时刻强一致。
  • E(Eventually Consistent)最终一致性: 经过一定时间窗口后,所有副本数据最终达到一致。
BASE vs ACID: 传统单机数据库遵循ACID(原子性、一致性、隔离性、持久性),而分布式系统在跨服务场景下往往选择BASE,用“最终一致”换取“高可用”和“水平扩展”。

3.3 最终一致性:分布式事务的核心目标

最终一致性是BASE理论的核心,也是分布式事务设计的终极目标。它不要求实时一致,但保证在“没有新更新的情况下,经过足够长的时间,所有副本最终达到一致”。

实现最终一致性的常见手段包括:

  • 重试机制: 失败操作通过指数退避重试,直到成功。
  • 补偿操作: 对已提交的成功操作执行反向操作(如退款、取消订单)。
  • 状态机与幂等: 每个操作具备幂等性,重复执行不产生副作用。
  • 异步对账: 通过定时任务或事件驱动,比对上下游数据并修复不一致。

3.4 分布式事务常见解决方案对比

业界针对不同一致性级别和性能要求,演化出四种主流方案。下表从核心原理、一致性强度、性能、适用场景四个维度进行对比:

方案 核心原理 一致性强度 性能 适用场景
2PC(两阶段提交) 协调者先询问所有参与者能否提交,再统一提交或回滚 强一致(CP) 低(同步阻塞) 短事务、跨库操作、对一致性要求极高的场景
TCC(Try-Confirm-Cancel) 业务层面拆分为预留、确认、取消三个阶段 强一致(CP) 中(无锁,但需业务补偿) 长事务、资金类、需要灵活回滚的业务
Saga 将长事务拆分为多个本地事务,每个事务有对应的补偿操作 最终一致(AP) 高(异步非阻塞) 跨微服务、流程长、允许中间状态的业务
消息表(本地消息表) 业务操作与消息写入在同一本地事务中,通过消息队列异步消费 最终一致(AP) 高(异步解耦) 订单与库存、积分、通知等异步解耦场景

3.5 四种方案详解

3.5.1 2PC(两阶段提交)

2PC引入协调者(Coordinator)角色,分为两个阶段:

  1. 准备阶段(Vote Phase): 协调者向所有参与者发送准备请求,参与者执行事务但不提交,返回Yes/No。
  2. 提交阶段(Commit Phase): 如果所有参与者都返回Yes,协调者发送Commit指令;否则发送Rollback指令。
2PC的缺陷: 同步阻塞(参与者持有资源锁)、单点故障(协调者宕机导致事务悬空)、数据不一致(第二阶段网络分区时部分节点收到Commit,部分未收到)。

3.5.2 TCC(Try-Confirm-Cancel)

TCC将每个服务操作拆分为三个接口,由业务代码实现:

  • Try: 资源预留/检查(如冻结库存100元)。
  • Confirm: 确认执行(扣减冻结库存,完成扣款)。
  • Cancel: 取消回滚(释放冻结库存)。

TCC避免了2PC的长锁问题,但要求业务方提供完整的补偿逻辑,开发成本较高。

3.5.3 Saga

Saga将长事务拆分为一系列本地事务(T1, T2, …, Tn),每个本地事务对应一个补偿操作(C1, C2, …, Cn)。执行方式有两种:

  • 编排(Choreography): 每个服务完成后发布事件,触发下一个服务。
  • 协调(Orchestration): 由协调器统一调度各服务执行顺序和补偿。

下图展示了Saga协调模式的核心流程:

Saga 协调模式(Orchestration) Saga 协调器 订单服务 库存服务 支付服务 T1: 创建订单 T2: 扣减库存 T3: 扣款 C3: 退款 C2: 恢复库存 C1: 取消订单

3.5.4 消息表(本地消息表)

消息表方案的核心思想是将“业务操作”与“消息发送”绑定在同一个本地事务中,保证两者原子性。典型流程如下:

  1. 业务服务在本地数据库插入业务记录,同时插入一条消息记录(状态为“待发送”)。
  2. 本地事务提交后,异步任务轮询消息表,将消息发送到MQ。
  3. 消费方处理消息,处理成功后回调确认,更新消息状态为“已发送”。
  4. 如果消费失败,消息表保留记录,由定时任务重试。
消息表 vs 事务消息: 消息表方案需要业务方自行维护消息表和轮询逻辑,而RocketMQ等消息中间件提供的“事务消息”将这一能力下沉到MQ层,降低了业务侵入性。两者本质都是“最终一致性+异步重试”。

3.6 方案选型建议

在事件风暴画布项目中,选择分布式事务方案应遵循以下原则:

业务特征 推荐方案 理由
短事务、跨库、强一致 2PC(Seata AT模式) 对一致性要求极高,可接受短暂阻塞
长事务、资金类、需灵活回滚 TCC 无锁,业务补偿可控
跨微服务、流程长、允许中间状态 Saga 异步非阻塞,适合事件驱动架构
异步解耦、最终一致 消息表 / 事务消息 高吞吐,与事件风暴画布的事件驱动模式天然契合