分布式事务是构建分布式系统时的核心挑战之一,它涉及到在多个服务或数据库之间保证事务的 ACID 特性(原子性、一致性、隔离性、持久性)。由于 CAP 定理和网络分区的存在,传统的本地事务机制无法直接适用于分布式环境。
一、什么是分布式事务?
分布式事务是指事务的参与者、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点上。
目标:确保所有参与节点要么全部提交事务,要么全部回滚事务。
二、常见的分布式事务解决方案
| 方案 | 类型 | 原理 | 优点 | 缺点 | 应用场景 |
|---|---|---|---|---|---|
| 2PC(两阶段提交) | 强一致性 | 协调者协调多个参与者完成提交或回滚 | 实现简单、强一致性 | 同步阻塞、单点故障 | 少量节点、对一致性要求高 |
| 3PC(三阶段提交) | 弱化单点 | 在 2PC 上引入超时机制 | 减少阻塞时间 | 复杂、仍可能脑裂 | 网络不稳定环境 |
| TCC(Try-Confirm-Cancel) | 补偿事务 | 模拟两阶段提交,业务层控制 | 高性能、高可用 | 开发复杂、需幂等设计 | 订单支付、库存扣减 |
| Saga 模式 | 补偿事务 | 顺序执行本地事务,失败则执行反向补偿操作 | 易于实现、响应快 | 不支持事务回滚到中间状态 | 长流程业务(如航班预订) |
| 本地消息表(Local Message Table) | 最终一致 | 本地事务写入消息,异步处理 | 简单可靠 | 依赖数据库、延迟较高 | 跨库数据同步 |
| 消息队列 + 事务消息(如 RocketMQ) | 最终一致 | 使用事务消息机制保证本地事务与消息发送一致性 | 解耦、高性能 | 实现复杂、需要 MQ 支持 | 异步解耦场景 |
| 最大努力通知 | 最终一致 | 定期重试通知下游系统 | 实现简单 | 可能失败、最终一致 | 对账、日志类场景 |
三、每种方案简介
1. 2PC(Two-phase Commit)
流程:
-
第一阶段(准备阶段):
- 协调者询问所有参与者是否可以提交事务。
- 参与者回复“同意”或“中止”。
-
第二阶段(提交/回滚阶段):
- 如果所有参与者都同意,则协调者发出提交命令;
- 否则,发出回滚命令。
优缺点:
- ✅ 强一致性
- ❌ 单点故障风险
- ❌ 性能差(阻塞)
- ❌ 网络问题可能导致不一致
适用场景:
- 数据库集群、XA 事务(如 Oracle、MySQL XA)
2. 3PC(Three-phase Commit)
是对 2PC 的改进,增加了超时机制:
- CanCommit:询问是否可以提交(不锁定资源)
- PreCommit:确认并锁定资源
- DoCommit:真正提交
优点:
- 减少了阻塞时间
- 提升了容错能力
缺点:
- 实现更复杂
- 仍然存在脑裂(网络分裂)问题
3. TCC(Try-Confirm-Cancel)
是一种典型的补偿型事务模型,需要开发者定义三个操作:
- Try(尝试):资源检查与预留(冻结库存、预授权)
- Confirm(确认):业务执行操作(扣除库存、支付成功)
- Cancel(取消):逆向操作(解冻库存、退款)
示例:
// Try
void prepareOrder() {
deductStock();
freezeBalance();
}
// Confirm
void confirmOrder() {
updateStatusToPaid();
}
// Cancel
void cancelOrder() {
returnStock();
refundBalance();
}
优点:
- 高性能、高可用
- 支持幂等、可扩展性强
缺点:
- 业务侵入性强
- 需要良好的异常处理机制
- 需要设计反向操作逻辑
适用场景:
- 电商交易、金融转账、订单支付等
4. Saga 模式
是一系列本地事务的组合,每个步骤都有一个对应的补偿动作。
流程:
- 执行 A → 成功
- 执行 B → 成功
- 执行 C → 失败 → 回退 B、回退 A
优点:
- 异步执行、无锁
- 快速失败、快速恢复
缺点:
- 不支持事务回滚到某个中间状态
- 日志记录复杂
适用场景:
- 长周期任务(如旅行预订、物流调度)
5. 本地消息表(Local Message Table)
将本地事务和消息发送绑定在一起,通过定时任务进行异步补偿。
步骤:
- 本地事务执行,同时插入一条“待发送”的消息到本地表。
- 消息服务定时扫描消息表,发送消息。
- 接收方消费消息后标记为已处理。
优点:
- 实现简单、可靠性高
缺点:
- 延迟高
- 需要额外的消息表维护
6. 事务消息(如 RocketMQ)
某些消息中间件支持事务消息机制:
- 生产者先发送“半消息”(未投递)
- 执行本地事务
- 根据事务结果决定提交或回滚该消息
优点:
- 解耦、异步、高性能
缺点:
- 依赖特定的消息中间件
- 实现较复杂
7. 最大努力通知
定期重试通知下游服务,直到对方确认收到为止。
优点:
- 实现简单
缺点:
- 不保证最终一致性
- 适合低优先级业务(如短信通知、日志上报)
四、如何选择合适的分布式事务方案?
| 要求 | 推荐方案 |
|---|---|
| 强一致性、少量节点 | 2PC / XA |
| 高可用、容忍短暂不一致 | TCC / Saga |
| 高性能、异步解耦 | 事务消息 / 本地消息表 |
| 低优先级、非关键路径 | 最大努力通知 |
五、主流开源框架支持
| 框架 | 支持协议 | 支持语言 | 说明 |
|---|---|---|---|
| Seata | 支持 AT、TCC、SAGA、XA | Java | 阿里巴巴开源,适合微服务架构 |
| ByteTCC | 支持 TCC | Java | 轻量级 TCC 框架 |
| Apache Camel Saga | Saga 模式 | Java | 支持流程编排 |
| RocketMQ / Kafka | 事务消息 | 多语言 | 消息驱动的事务机制 |
| Atomikos / Bitronix | XA 2PC | Java | 传统分布式事务管理器 |
六、总结
| 方案 | 是否强一致 | 是否异步 | 是否有侵入性 | 是否推荐 |
|---|---|---|---|---|
| 2PC | ✅ 是 | ❌ 否 | ❌ 否 | ⚠️ 慎用 |
| 3PC | ✅ 是 | ❌ 否 | ❌ 否 | ⚠️ 慎用 |
| TCC | ❌ 否 | ✅ 是 | ✅ 是 | ✅ 推荐 |
| Saga | ❌ 否 | ✅ 是 | ✅ 是 | ✅ 推荐 |
| 本地消息表 | ❌ 否 | ✅ 是 | ✅ 是 | ✅ 推荐 |
| 事务消息 | ❌ 否 | ✅ 是 | ✅ 是 | ✅ 推荐 |
| 最大努力通知 | ❌ 否 | ✅ 是 | ✅ 是 | ✅ 推荐 |
2万+

被折叠的 条评论
为什么被折叠?



