分布式事务
# 分布式事务详解
在单体应用中,事务(Transaction)通常是一个数据库层面的概念,用于保证操作的ACID特性——原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。然而,当系统拆分成多个微服务、每个服务拥有独立的数据源时,传统的本地事务机制便无法直接满足全局一致性的要求。这时,我们就需要引入分布式事务(Distributed Transaction)。在讲分布式事务实现具体方案之前先了解一些分布式的基础。
# 什么是分布式事务
分布式事务是指跨越多个独立系统、数据库或服务的事务操作,需要在分布式环境中确保所有参与节点的数据一致性。
举个例子,假设一个电商系统中,订单服务负责创建订单,库存服务负责扣减库存。这两个操作必须要么同时成功,要么全部回滚,否则就会产生数据不一致的问题。

# 从分布式理论理解
# CAP 定理:一致性与可用性的权衡

CAP 定理指出,在分布式系统中,当出现网络分区(Partition Tolerance)时,系统无法同时满足:
- C(Consistency)一致性:所有节点对同一请求返回相同结果;
- A(Availability)可用性:系统始终可响应请求;
- P(Partition Tolerance)分区容忍性:系统能容忍部分节点或网络故障。
由于分区不可避免,系统设计只能在 一致性 和 可用性 之间权衡。
例如:
- 银行转账系统偏向 一致性优先(CP);
- 电商商品展示系统则偏向 可用性优先(AP)。
CAP 定理告诉我们:分布式事务不是要“完美解决矛盾”,而是要在业务可接受范围内做选择。
# BASE 理论:从强一致到最终一致
BASE 理论 是对 CAP 的工程化扩展,其核心思想是:
- Basically Available:系统允许部分功能退化以保持整体可用;
- Soft state:系统状态可以暂时不一致;
- Eventual consistency:经过一段时间后,数据最终会达到一致。
在很多业务场景下,我们并不要求实时一致,而是允许“最终一致”。例如,电商下单后几秒钟内库存同步完成,并不会影响用户体验。
BASE 理论的目标是:通过异步、重试和补偿机制,以更低成本实现可接受的一致性。
# 分布式事务的选择与权衡
本地事务依托数据库的 ACID 特性(原子性、一致性、隔离性、持久性)即可实现,但分布式场景下,这一闭环被打破,主要面临三大挑战:
网络不可靠:服务间通信依赖网络,存在延迟、丢包、超时等问题,无法保证 “一次调用必然成功”;
数据分散:事务涉及的数据源分布在不同节点(如订单库、库存库、支付库),无法通过单库的锁机制实现全局隔离;
节点故障:任一参与节点(服务、数据库、中间件)宕机,都可能导致部分操作成功、部分失败,数据陷入不一致状态。
这些挑战决定了:不存在 “完美适配所有场景” 的分布式事务方案,任何选择都需以牺牲某一维度的特性为代价。
在分布式系统中,为了保证多个节点之间的数据一致性,需要设计相应的事务机制。事务机制大体分为两类:刚性事务(Rigid Transaction) 与 柔性事务(Flexible Transaction)。它们分别对应分布式理论中的 CP 与 AP 取向。

# 分布式事务方案实现
# 一、2PC:强一致性的“经典方案”
原理概述
2PC(Two-Phase Commit,两阶段提交)将事务划分为“准备阶段”和“提交阶段”,由“协调者”统一管理所有“参与者”。
- 准备阶段(Prepare)
- 协调者向所有参与者发送“准备请求”。
- 参与者执行本地事务但不提交,若成功则返回“就绪”,否则返回“失败”。
- 提交阶段(Commit / Rollback)
- 若所有参与者均返回“就绪”,协调者发送“提交请求”,各参与者执行提交操作。
- 若任一参与者返回“失败”,协调者发送“回滚请求”,各参与者执行回滚。

权衡分析
- 优点:
- 利用数据库自身的事务能力实现提交与回滚,无需侵入业务代码。
- 劣势:
- 性能差: 需两次通信,且参与者在等待协调者指令期间会锁定资源,导致并发吞吐量低。
- 资源浪费: 若部分参与者在第一阶段故障,其他参与者的事务操作最终需回滚,浪费计算与锁资源。
# 二、3PC:升级版的“改进型强一致方案”
3PC(三阶段提交协议)在 2PC 基础上新增“预提交阶段(PreCommit)”并引入超时机制,以降低阻塞与资源浪费风险。
- 阶段一:CanCommit(准备阶段)
- 协调者询问参与者是否可执行事务。
- 参与者仅检查资源是否可用,不执行事务。若可执行返回“同意”,否则返回“拒绝”。
- 阶段二:PreCommit(预提交阶段)
- 若全部参与者同意,协调者发送“PreCommit 请求”。
- 参与者执行本地事务但不提交,并返回“预提交成功”。
- 若有参与者拒绝或超时,协调者发送“中断请求”,所有参与者终止操作。
- 阶段三:DoCommit(提交/回滚阶段)
- 若全部参与者预提交成功,协调者发送“Commit 请求”,参与者提交事务并释放资源。
- 若有失败或超时,协调者发送“Rollback 请求”,参与者回滚。

说明
3PC 解决了部分 2PC 阻塞问题,但增加了一次通信开销,实际应用较少。仅在对强一致性要求极高(如金融系统)时使用。
# 三、AT 模式:基于最终一致性的轻量方案
AT 模式是 Seata 中最常用的事务模式,基于 UNDO LOG 实现最终一致性。
核心思想:通过记录数据快照,在回滚时恢复原始状态。
执行流程:
- 阶段一:事务执行与记录快照
- 参与者执行并直接提交本地事务。
- 同时记录数据原始值(快照)至
undo log。
- 阶段二:协调与回滚
- 若所有参与者成功,协调者通知删除对应的
undo log。 - 若有失败,协调者通知相关参与者根据
undo log回滚数据。
- 若所有参与者成功,协调者通知删除对应的

与 2PC 的对比:
| 对比维度 | AT 模式 | 2PC |
|---|---|---|
| 一阶段操作 | 直接提交事务 | 不提交,锁定资源 |
| 回滚机制 | 依赖 undo log 数据快照 | 依赖数据库事务机制 |
| 一致性类型 | 最终一致性 | 强一致性 |
# 四、TCC:性能优先的“补偿型方案”
TCC(Try-Confirm-Cancel)是业务层面的两阶段提交模型,需要为每个业务操作实现三个对应方法。
- Try(尝试):检查并预留资源(例如冻结库存)。
- Confirm(确认):实际执行操作(例如扣减库存),需保证幂等性。
- Cancel(取消):释放预留资源,亦需保证幂等性。

权衡分析
- 优势:
- 性能高,无锁阻塞;
- 可用性强,无单点依赖;
- 灵活性高,支持复杂业务自定义。
- 劣势:
- 业务侵入性强,需改造业务代码;
- 幂等与回滚实现复杂;
- Cancel 执行失败需人工干预或补偿任务。
适用场景: 高并发、性能敏感、逻辑可拆分为 Try-Confirm-Cancel 的业务(如支付、库存管理、秒杀活动)。
# 五、SAGA:长事务的“异步补偿方案”
Saga 事务将一个全局事务拆分为多个按顺序执行的本地事务,每个本地事务执行成功后触发下一个。若中途失败,通过反向补偿操作回滚之前已成功的事务。

权衡分析
- 优势:
- 适合长事务,无锁阻塞;
- 性能与可用性高;
- 业务侵入性低于 TCC。
- 劣势:
- 仅保证最终一致性;
- 需为每个本地事务实现补偿逻辑;
- 调试与监控复杂。
适用场景: 跨服务长事务、可接受中间不一致的系统(如订单履约、供应链管理)。
# 六、本地消息表 + 消息队列:低侵入的“最终一致性方案”
原理:
在执行业务操作的同时,将需要发送的消息存入本地消息表,并通过异步任务推送至消息队列实现最终一致。
- 阶段一:业务执行与消息记录
- 执行本地事务并提交。
- 将消息写入本地消息表(状态为“待发送”)。
- 阶段二:异步消息投递
- 定时任务扫描“待发送”消息,推送至 MQ。
- 消费者接收并执行业务逻辑,若失败则重试或进入死信队列。

权衡分析
- 优势:
- 侵入性低,改动小;
- 实现简单,依赖成熟 MQ;
- 高性能与高可用。
- 劣势:
- 弱一致性,存在延迟;
- 需处理消息幂等;
- 存在消息丢失风险,需重试机制。
# 七、最大努力通知:兜底型最终一致性方案
原理:
发起方通过定时任务多次重试通知接收方,直到收到确认响应或达到最大重试次数。若仍失败,则交由人工处理。
权衡分析
- 优势: 实现最简单,侵入性最低,成本极低。
- 劣势: 一致性最弱,可能出现消息未送达。
适用场景: 对一致性要求低、可人工干预的非核心业务(如短信、邮件通知)。