2PC 与 TCC
2PC 协调事务资源的提交决定,TCC 协调业务预留。本文讲解两阶段状态、阻塞、幂等与乱序处理。
1. 面试核心
先记住这几条,再读正文- 两阶段提交。 2PC 先持久化 prepare 状态,再执行协调器的提交或回滚决定。卡 · 2PC 准备阶段
- 准备状态的阻塞。 已准备参与者在决定未知时保留资源,等待恢复协议处理。
- 业务资源预留。 TCC 的 Try 预留资源,Confirm 使用预留,Cancel 释放预留。
- 分支幂等与乱序。 TCC 分支状态与资源变化共同提交,以处理重复、空回滚和悬挂。卡 · 分支状态与并发转换
- 提交决定恢复。 协调器的提交决定持久化后,参与者按该决定重试完成。
2. 2PC 准备阶段
协调器要求各参与者 prepare。参与者完成约束检查,并持久化足够的恢复信息。投赞成票后,它承诺可以执行最终决定。
数据库参与者会保留锁等事务资源。若某个参与者明确拒绝,协调器记录 abort,并通知回滚。
3. 2PC 提交阶段
所有参与者准备成功后,协调器持久化 commit 决定。随后发送提交通知。响应丢失时,通知可以重复发送。
参与者重启后根据恢复日志查询决定。决定未知时,自行回滚会与已提交分支冲突。因此,协议在这类状态下会阻塞。协调器高可用能缩短故障时间,但网络分区仍会影响恢复。
2PC 保证提交决定一致。跨库读取的隔离还依赖事务管理与读协议。
4. 资源管理器支持
XA 和数据库 prepared transaction 提供持久准备状态。普通 HTTP 接口需额外实现相同的恢复责任。
PostgreSQL 18 可用 pg_prepared_xacts 查看准备事务。长时间 prepared 会保留锁,并影响 VACUUM 回收。处理前应核对协调器决定,再执行对应的提交或回滚。
参与者数量、网络往返和日志持久化共同增加耗时。短事务更适合这种资源持有方式。
5. TCC 的 Try
Try 检查条件并预留库存、额度或席位。Confirm 使用已预留资源,Cancel 释放预留。每个阶段用本地事务保存结果。
Try 提交后,预留状态对其他请求可见。数据库锁随本地事务结束而释放。预留资源则继续占用,直到分支进入终态。
6. Confirm 与 Cancel 的幂等
协调器使用全局事务 ID 和分支 ID 标识操作。重复 Confirm 返回已有确认结果。重复 Cancel 返回已有取消结果。
Confirm 消费 Try 已经预留的资源。新增业务检查应尽量在 Try 完成。全局 commit 已确定后,临时执行失败需继续重试。
7. 空回滚与悬挂
Cancel 可以先于延迟的 Try 到达。此时分支记录取消终态,但没有资源需要释放。这是空回滚。
迟到 Try 必须检查取消终态,并拒绝重新预留。否则 Cancel 完成后又出现占用,形成悬挂。
7.1 分支状态与并发转换
可用下列状态描述分支:
| 当前状态 | Try | Confirm | Cancel |
|---|---|---|---|
| 无记录 | 创建预留与 TRIED。 | 返回异常,核对协调状态。 | 写入 CANCELLED。 |
| TRIED | 返回已有预留结果。 | 消费预留并转 CONFIRMED。 | 释放预留并转 CANCELLED。 |
| CONFIRMED | 返回已有结果。 | 返回成功。 | 拒绝相反终态。 |
| CANCELLED | 拒绝迟到 Try。 | 拒绝相反终态。 | 返回成功。 |
分支唯一键限制并发创建。状态检查、资源变化和终态更新需共同提交。标记保留时间应覆盖协议重试窗口。
预留超时应触发全局决定核对。资源方若在 commit 后擅自释放,会导致 Confirm 失败。超时本身只提供时间信号。
8. TCC 的成本
每项资源都需实现三个阶段和分支记录。协调故障期间,预留会持续减少可用库存或额度。监控需跟踪最老预留和重试次数。
外部接口若无预留与幂等能力,应重新选择业务方案。长流程的补偿机制见Saga。
9. 方案选择
2PC 适合支持持久准备、可以接受持锁的短事务。TCC 适合具备明确预留模型的业务资源。
两者都需持久化全局决定,并监控长时间中间状态。异常解除以权威决定为准,操作过程保留审计。
10. 常见问题
10.1 协调器高可用与阻塞
高可用降低协调器单点故障影响。参与者失联且决定未知时,仍需等待或执行恢复协议。
10.2 Cancel 与数据库回滚
Cancel 是新的本地业务事务。它释放 Try 已提交的预留。数据库 rollback 则撤销当前尚未提交的修改。
11 · 面试题卡片
11.1 2PC 和 TCC 的差异是什么,各自有哪些失败状态
出现公司:阿里巴巴
考察重点
- prepare、持久决定和不确定等待。
- Try 预留、Confirm/Cancel 幂等。
- 空回滚、悬挂、资源持有和恢复。
参考回答
2PC 在资源层协调原子提交,TCC 在业务层协调预留。
2PC 参与者持久化 prepare 后保留事务资源。协调器记录最终决定,再驱动各分支完成。决定未知时会阻塞。
TCC 的 Try 提交预留,Confirm 消费预留,Cancel 释放预留。幂等和分支状态处理重复与乱序。Cancel 先到需记录终态,迟到 Try 应拒绝。TCC 减少长数据库锁,但增加业务模型与恢复成本。
11.2 TCC 的 Cancel 先到、Try 后到时,怎样避免资源再次被占用?
出现公司:暂无已核验的公开来源(本站自测)
考察重点:空回滚、悬挂与状态原子性。
相关内容:分支状态与并发转换。
参考回答
Cancel 应先写入取消终态,迟到 Try 根据该状态拒绝预留。
唯一键防止两个请求各建一条分支。状态转换与资源变化使用同一本地事务。取消标记需覆盖重试窗口,过早清理会让迟到请求重新执行。