先准备,再统一决定

跨多个资源的事务不能只看某一处是否完成,就假定其他参与者也会完成。两阶段提交在决定提交前,让所有参与者确认自己已经准备好;协调者再把相应决定传给参与者。

准备成功不等于事务效果已经正式公开。PostgreSQL提供PREPARE TRANSACTION、COMMIT PREPARED与ROLLBACK PREPARED,把准备和最终结束分成明确操作,供外部事务管理器协调。

参考:[1] [2] [3]

准备状态需要恢复与清理

PostgreSQL准备后的事务脱离原会话,后续可以由其他会话按事务标识完成。该机制保存恢复所需状态,使数据库崩溃重启后仍有办法继续处理,而不是把准备信息只留在一个客户端变量里。

准备状态也不是免费的暂停。事务继续持有相应锁,长期不结束还会妨碍VACUUM等维护。外部管理器必须跟踪这些事务,并及时决定提交或撤销;不能把准备接口当成无限期保留资源的普通存档工具。

参考:[3] [2]

故障可能使参与者无法自行决定

经典两阶段提交可能在协调者故障后阻塞。参与者已经准备,却没有可靠获知最终决定时,不能各自随意选择相反结果;Gray与Lamport把这种决定不确定性与协议的可用性限制联系起来。

设计恢复时须区分安全与进展:不能让一个参与者提交、另一个撤销,也希望在适当条件下最终完成。复制协调决定等其他方案需要额外协议,不能只靠把超时调短就消除准备状态中的不确定性。

参考:[1] [2]