三阶段协议

在两阶段的基础上进行扩展,将第一阶段划分两部,cancommit + precommit,第三阶段则为 docommit

第一阶段 cancommit

该阶段协调者会去询问各个参与者是否能够正常执行事务,参与者根据自身情况回复一个预估值,相对于真正的执行事务,这个过程是轻量的

第二阶段 precommit

本阶段协调者会根据第一阶段的询盘结果采取相应操作,询盘结果主要有 3 种:

第一阶段响应 步骤
所有的参与者都返回确定 1.协调者向所有的事务参与者发送事务执行通知
2.参与者收到通知后执行事务但不提交
3.参与者将事务执行情况返回给客户端
一个或多个参与者返回否定信息 无法执行,向各个参与者发出 abort 通知,请求退出预备状态
协调者等待超时 同上

3PC回滚

第三阶段 docommit

如果第二阶段事务未中断,那么本阶段协调者将会依据事务执行返回的结果来决定提交或回滚事务,分为 3 种情况:

第二阶段响应 步骤
所有的参与者都能正常执行事务 1.向所有参与者提交commit
2.所有参与者在收到通知之后执行 commit 操作释放资源
3.参与者向协调者反馈事务提交结果
一个或多个参与者执行事务失败 协调者认为事务无法成功执行
1.向所有参与者提交rollback
2.所有参与者执行rollback回滚
3.参与者向协调者反馈事务回滚结果
协调者等待超时 同上

事务提交流程图:

3PC提交

事务回滚流程图:

3PC回滚

在本阶段如果因为协调者或网络问题,导致参与者迟迟不能收到来自协调者的 commit 或 rollback 请求,那么参与者将不会如两阶段提交中那样陷入阻塞,而是等待超时后继续 commit,相对于两阶段提交虽然降低了同步阻塞,但仍然无法完全避免数据的不一致

特点

  • 降低了阻塞与单点故障:
    • 参与者返回 CanCommit 请求的响应后,等待第二阶段指令,若等待超时/协调者宕机,则自动 abort,降低了阻塞;
    • 参与者返回 PreCommit 请求的响应后,等待第三阶段指令,若等待超时/协调者宕机,则自动 commit 事务,也降低了阻塞;
  • 数据不一致问题依然存在
    • 比如第三阶段协调者发出了 abort 请求,然后有些参与者没有收到 abort,那么就会自动 commit,造成数据不一致