← 每日面试题 学习看板

什么是分布式事务中的两阶段提交(2PC)

面试题/02架构设计题/02分布式/02分布式事务/什么是分布式事务中的两阶段提交(2PC).md

面试记录 2026-09-23

题目:什么是分布式事务中的两阶段提交(2PC)

难度:low

评分:⭐⭐⭐☆☆

我的回答

分布系统中,两阶段提交 2PC,本质就是把单次提交的请求,一个事务内的单次提交请求分作两次去进行。先进行一次预提交,大家确认一下各自能否进行提交,能否完成提交。如果确认完状态是可以的,在这个阶段完成之后,就进行正式的提交,将所有的资源进行处理,完成一整次的提交。它的好处本质上就是防止在提交过程中,出现一些服务没有办法准备,没有准备好,导致已经提交的事务无法正常进行。而提前做了确认,确认大家预留了,这样可以确保成功率,事务的成功率,事务的稳定性。但是衍生一个问题,就是它需要产生延迟,或者说等待。因为事务提交第一个发起者要等后续的其他参与者确认之后才能够进行提交,这就是 2PC 的问题。

点评

评分:⭐⭐⭐☆☆

优点:

不足:

补充:

  1. 协调者发 Prepare → 参与者写业务日志 + redo log 到本地磁盘,返回 Prepare OK / Fail
  2. 若全部 OK → 协调者发 Commit → 参与者执行提交,释放锁
  3. 若任一 Fail → 协调者发 Rollback → 参与者回滚

完整讲解

第一部分:知识重点剖析

核心考点定位:考察对 2PC 协议两阶段结构的精确理解,以及能否识别其致命缺陷(阻塞)而非仅说"延迟高"。

知识点拆解:

  1. 角色分工:协调者(Txn Coordinator)+ 参与者(Participants),通常业务应用是协调者,数据库是参与者
  2. 阶段 1 - Prepare(准备阶段):
  1. 阶段 2 - Commit(提交阶段):
  1. 崩溃恢复的关键:redo log 是 2PC 能在故障后收敛的唯一依据
  2. 致命缺陷:协调者崩溃在"写日志→发指令"之间 → 参与者永久阻塞

第二部分:考察方向与延伸递进

考察方向:

延伸递进面试题:

  1. "为什么 2PC 需要写 redo log?如果不写,会出现什么问题?"
  1. "协调者宕机后,参与者持有了锁无法释放,业务上会看到什么现象?如何主动恢复?"
  1. "MySQL 的 XA 事务本质就是 2PC,为什么生产上不建议用?"

第三部分:面试者参考回答(300-600 字口语化)

面试官您好,2PC 是分布式事务里最经典的强一致协议,核心思想是把一次提交拆成两个阶段,用协议来弥补没有单一事务边界的问题。 它有两个角色:协调者和参与者。协调者通常是业务应用,参与者是各个数据库或微服务。 第一阶段是 Prepare。协调者向所有参与者发"你能提交吗"的询问。每个参与者收到后,先在本地执行事务但不提交,同时把这次操作的日志写到 redo log 并落盘——这一步是关键,因为 redo log 是参与者"我能恢复的判断依据"。然后参与者持有资源锁等待协调者下一步指令,返回 Prepare OK 或者 Fail。 第二阶段是 Commit。如果所有参与者都返回 OK,协调者发 Commit,参与者真正提交并释放锁;如果有一个返回 Fail,协调者发 Rollback,所有参与者回滚。 这里有个关键点:redo log 让 2PC 具备崩溃恢复能力。假设协调者在发出 Commit 之前宕机,参与者通过查询 redo log 就能知道"我当时是准备 OK 还是 Fail",恢复后可以自行决定是否提交;如果没有 redo log,参与者只能被动等待或者超时回滚,就可能造成状态丢失。 但 2PC 最大的问题不是延迟,而是阻塞。想象一下:协调者在"写完日志→发 Commit"这个窗口宕机了,所有参与者都持有资源锁,谁也无法推进,事务就卡住了。业务上会看到大量连接被占用、其他事务无法执行。这是 CP 系统的必然代价——为了保证一致性,牺牲可用性。 3PC 想通过引入"预提交"阶段来缓解阻塞,但工程实践依然没有替代 2PC,因为网络分区依然存在。所以现在主流方案要么用 XA(MySQL 内置),要么转向柔性事务——TCC、Saga、消息驱动的最终一致方案,用"最终一致"换"可用性"。