面试知识库
进阶

2PC与3PC#

一句话答案#

2PC 两阶段提交(prepare→commit),问题:协调者单点+参与者阻塞;3PC 增加 canCommit 预检+超时机制减少阻塞。

核心要点

2PC(Two-Phase Commit)两阶段提交:

引入一个协调者(Coordinator)来统一调度多个参与者(Participant)的事务提交。

2PC 的四大问题:

问题说明
同步阻塞阶段一执行完后,所有参与者锁定资源等待协调者指令,期间资源被阻塞
单点故障协调者挂了,参与者一直等待,资源无法释放,整个事务阻塞
脑裂/数据不一致阶段二协调者发 Commit 后挂了,部分参与者收到 Commit 提交了,部分没收到未提交
过于保守任一参与者失败或超时都会回滚整个事务,没有容错机制

3PC(Three-Phase Commit)三阶段提交:

在 2PC 的基础上做了两个改进:(1) 引入超时机制;(2) 增加 CanCommit 预询问阶段。

2PC vs 3PC 对比:

维度2PC3PC
阶段数23(多了 CanCommit 预询问)
参与者超时无(一直等协调者)有(超时自动提交,减少阻塞)
阻塞程度高(协调者挂了就完全阻塞)低(参与者可超时自动决策)
一致性风险有(脑裂导致部分提交)仍有(超时自动提交可能和实际不一致)
实际应用MySQL XA 事务较少使用(复杂且仍不能完全避免不一致)
面试回答(2分钟版)

2PC 是分布式事务最经典的协议,分为 prepare 和 commit 两个阶段:协调者先问所有参与者”能不能提交”,参与者执行事务但不提交并锁住资源,全部返回 YES 后协调者再发 commit 指令正式提交。核心问题有三个——协调者单点故障会导致全体阻塞、参与者在 prepare 后一直持锁等待、以及网络分区时部分节点 commit 部分没收到造成数据不一致。3PC 在此基础上做了两个改进:增加 CanCommit 预询问阶段,先轻量探测再锁资源;引入参与者超时机制,等不到协调者指令就自动提交,减少了阻塞但仍可能因超时自动提交导致不一致。实际工程中 2PC 用于 MySQL XA 事务等场景,而纯 3PC 很少使用,更多是用 TCC、SAGA 等柔性事务方案来解决分布式一致性问题。

追问与易错

追问方向:

  • “2PC 的阻塞问题?”→ Prepare 后参与者持锁等待协调者指令,协调者宕机则全体阻塞资源无法释放,且无超时机制
  • “3PC 真解决了问题吗?”→ 缓解了阻塞(参与者超时自动提交),但超时自动提交可能与实际结果不一致,所以仍不完美
  • “Seata AT 和传统 2PC 区别?”→ Seata AT 一阶段就提交本地事务(不持锁等待),通过 undo_log 实现回滚,性能远优于传统 2PC 的长时间持锁

易错点:

  • ❌ 2PC 保证强一致——网络分区时仍可能不一致
  • ❌ 3PC 完美解决了 2PC——超时自动提交可能不一致