分布式系统【六、两阶段提交(2PC)与三阶段提交(3PC)协议详解】
两阶段提交(2PC)与三阶段提交(3PC)协议详解
系列专题第六篇 · 分布式系统基础指南
一、引言
在分布式系统中,一致性问题不仅出现在副本复制(如 Raft、Paxos),也出现在 分布式事务 中。
一个事务可能跨越多个数据库或服务节点,例如:
- 电商系统中的「下单 → 扣库存 → 扣余额 → 生成订单」。
- 金融系统中的「账户转账」。
这些操作必须遵循 ACID 中的一致性:要么全部成功,要么全部失败。
为解决跨节点事务一致性问题,业界提出了 两阶段提交(2PC) 和 三阶段提交(3PC) 协议。
二、2PC 协议(Two-Phase Commit)
2PC 是分布式事务的经典协议,分为两个阶段:准备阶段(Prepare) 和 提交阶段(Commit)。
阶段一:准备(Voting / Prepare)
- 协调者(Coordinator) 向所有参与者(Participant)发送事务请求。
- 每个参与者执行事务操作(如写入数据库),但不提交,只写入日志。
- 参与者向协调者返回「投票结果」:同意提交(Yes)或拒绝提交(No)。
阶段二:提交(Commit)
- 若所有参与者返回 Yes:协调者向所有参与者发送 Commit 指令,事务提交成功。
- 若有任意参与者返回 No:协调者发送 Rollback 指令,所有参与者回滚事务。
三、2PC 的问题
虽然简单,但 2PC 有以下缺陷:
-
阻塞问题
- 如果协调者宕机,参与者会一直阻塞,无法继续事务。
-
单点问题
- 协调者是单点故障,影响整个事务。
-
数据不一致
- 在第二阶段,若部分参与者收到 Commit,部分没收到(网络分区),会导致数据不一致。
👉 2PC 只能保证 原子性(Atomicity),但在高并发、网络故障场景下并不可靠。
四、3PC 协议(Three-Phase Commit)
为解决 2PC 的阻塞问题,提出了 3PC。
3PC 在 2PC 基础上增加了一个阶段(Pre-Commit),流程如下:
阶段一:CanCommit
- 协调者询问所有参与者是否可以执行事务。
- 参与者检查资源是否可用,返回 Yes/No。
阶段二:PreCommit
- 如果所有参与者返回 Yes,协调者发送 PreCommit 指令。
- 参与者执行事务操作,并进入「预提交」状态,但仍未提交。
- 如果有参与者返回 No,则协调者直接发送 Abort 指令。
阶段三:DoCommit
- 如果协调者收到所有参与者的确认,则发送 DoCommit 指令,参与者提交事务。
- 若超时未收到确认,参与者会自动提交或回滚,避免永久阻塞。
五、2PC vs 3PC 对比
| 特性 | 2PC | 3PC |
|---|---|---|
| 提交阶段 | 2 阶段 | 3 阶段 |
| 阻塞性 | 强阻塞 | 弱阻塞 |
| 单点故障 | 有(协调者) | 缓解(超时机制) |
| 一致性 | 较弱 | 较强,但仍可能出错 |
| 工程实现 | 简单,广泛使用 | 复杂,理论价值更高 |
六、工程应用与改进
-
分布式数据库事务
- MySQL XA、Oracle 等都实现了 2PC 协议。
-
消息队列 + 本地事务
- RocketMQ 等采用「消息事务」方案,结合补偿机制。
-
补偿事务(TCC 模型)
- Try-Confirm-Cancel,适用于业务层控制,避免阻塞。
-
结合一致性协议(Raft / Paxos)
- 实际工程中,常用 Raft/ZAB 来保证协调者的高可用,从而避免单点问题。
七、总结
- 2PC:简单直观,但有阻塞和单点问题。
- 3PC:增加 PreCommit 阶段,缓解阻塞问题,但复杂度更高,工程实践少。
- 现代分布式系统:大多采用「2PC + 补偿机制」或基于 Raft/ZAB 的强一致存储 来实现分布式事务。
本文来自博客园,作者:NeoLshu,转载请注明原文链接:https://www.cnblogs.com/neolshu/p/19120389

浙公网安备 33010602011771号