什么是TCC?什么是二阶段提交?三阶段提交?
在分布式系统中,TCC、**二阶段提交(2PC)和三阶段提交(3PC)**是解决分布式事务一致性的核心协议。它们的核心目标是协调多个参与节点的事务操作,确保数据最终一致性。
1. 二阶段提交(2PC)
核心思想
通过协调者(Coordinator)分两个阶段协调所有参与者(Participants)的事务操作,保证所有节点要么全部提交,要么全部回滚。
执行流程
-
准备阶段(Prepare Phase)
- 协调者向所有参与者发送 Prepare 请求,询问是否可以提交事务。
- 参与者执行事务操作(但不提交),记录 Undo/Redo 日志,返回 Yes/No。
-
提交阶段(Commit Phase)
- 所有参与者返回 Yes → 协调者发送 Commit 命令,参与者正式提交事务。
- 任一参与者返回 No → 协调者发送 Rollback 命令,参与者回滚事务。
特点与问题
- 优点:强一致性保证,实现简单。
- 缺点:
- 同步阻塞:参与者等待协调者指令时处于阻塞状态。
- 单点故障:协调者宕机会导致参与者无限等待。
- 数据不一致:协调者发送 Commit 后部分参与者宕机,可能导致部分提交。
适用场景
- 传统数据库分布式事务(如 XA 协议)。
- 对一致性要求高、参与者较少的场景。
2. 三阶段提交(3PC)
核心改进
在 2PC 的基础上增加 预提交阶段(Pre-Commit),并引入超时机制,降低阻塞风险。
执行流程
-
CanCommit 阶段
- 协调者询问参与者是否具备提交条件(资源是否充足)。
- 参与者返回 Yes/No。
-
PreCommit 阶段
- 所有参与者返回 Yes → 协调者发送 PreCommit,参与者锁定资源并返回 ACK。
- 任一参与者返回 No → 协调者发送 Abort,参与者终止事务。
-
DoCommit 阶段
- 协调者发送最终 Commit 或 Rollback 指令。
- 参与者超时未收到指令则默认提交(基于状态推测)。
特点与问题
- 优点:
- 降低阻塞概率(超时自动提交/回滚)。
- 减少单点故障影响。
- 缺点:
- 网络分区时仍可能数据不一致。
- 实现复杂,实际应用较少。
适用场景
- 对可用性要求稍高,但仍需强一致性的系统。
3. TCC(Try-Confirm-Cancel)
核心思想
通过业务逻辑的 补偿机制 实现最终一致性,将事务拆分为三个阶段:
- Try:预留资源(如冻结库存)。
- Confirm:确认操作(如扣减库存)。
- Cancel:补偿回滚(如释放库存)。
执行流程
-
Try 阶段
- 调用所有参与者的
try()
接口,预留资源(如检查并冻结库存)。 - 若所有参与者返回成功 → 进入 Confirm 阶段。
- 任一参与者失败 → 进入 Cancel 阶段。
- 调用所有参与者的
-
Confirm/Cancel 阶段
- Confirm:调用所有参与者的
confirm()
,提交预留资源(如真实扣减库存)。 - Cancel:调用所有参与者的
cancel()
,释放预留资源(如解冻库存)。
- Confirm:调用所有参与者的
特点与问题
- 优点:
- 无全局锁,高并发性能好。
- 支持异构系统(如混合数据库和 HTTP 服务)。
- 缺点:
- 业务侵入性高:需为每个服务设计 Try/Confirm/Cancel 接口。
- 需保证幂等性:网络重试可能导致重复调用,需业务层处理。
适用场景
- 高并发业务(如电商秒杀、金融支付)。
- 需最终一致性的长事务(如跨系统订单处理)。
对比总结
特性 | 2PC | 3PC | TCC |
---|---|---|---|
一致性 | 强一致性 | 强一致性 | 最终一致性 |
性能 | 低(阻塞等待) | 中(减少阻塞) | 高(无锁) |
复杂度 | 低 | 高 | 高(需业务改造) |
容错能力 | 差(单点故障) | 中(超时机制) | 高(补偿机制) |
适用场景 | 传统数据库事务 | 改进型强一致性系统 | 高并发、异构系统 |
实际案例
2PC 案例:XA 事务
-- MySQL XA 事务示例
XA START 'tx1'; -- 开启事务
UPDATE account SET balance = balance - 100 WHERE user_id = 1;
XA END 'tx1';
XA PREPARE 'tx1'; -- 准备阶段
XA COMMIT 'tx1'; -- 提交阶段
TCC 案例:电商下单
- Try 阶段:
- 订单服务:生成预订单(状态为“处理中”)。
- 库存服务:冻结商品库存(如
freeze_stock
表)。
- Confirm 阶段:
- 订单服务:更新订单状态为“已支付”。
- 库存服务:扣减真实库存。
- Cancel 阶段(若支付失败):
- 订单服务:标记订单为“已取消”。
- 库存服务:解冻库存。
选择建议
- 强一致性需求 → 2PC(如银行转账)。
- 高可用与最终一致性 → TCC(如电商秒杀)。
- 需改进 2PC 的阻塞问题 → 3PC(较少使用,可结合消息队列优化)。