三阶段提交
将二阶段提交的“提交事务请求”过程分为两步。
三阶段包括:CanCommit、PreCommit、doCommit
第一阶段:CanCommit
1、事务询问:协调者向各参与者发送包含事务那内容的CanCommit请求。询问是否可以执行事务提交操作。并等待响应。
2、询问响应:各参与者可以顺利执行任务,返回响应yes。并进入预备状态。否则响应no
第二阶段:PreCommit
根据各参与者的响应决定是否进行事务的PreCommit操作。包含两种情况:
事务预提交:参与者全部返回yes
1、 预提交请求:协调者向各参与者发送PreCommit请求,并进入Prepared阶段。
2、事务预提交:参与者接收到preCommit请求后,会执行事务操作。并将Undo和Redo信息记录到事务日志中。
3、反馈响应:反馈给协调者Ack响应。并等待最终指令。
中断事务:任意参与者返回no,或等待超时
1、中断请求:协调者向各参与者发送abort请求
2、中断事务:无论接收到abort请求,或是等待请求超时,参与者都会中断请求。
第三阶段:doCommit
该阶段进行真正的事务提交。有以下两者情况
执行提交:
1、提交请求:协调者收到所有参与者的Ack响应,将从 “预提交状态” 变为 “提交状态” ,并向各参与者发送doCommit请求
2、事务提交:参与者收到doCommit请求,会正式执行事务提交操作,并在完成提交后释放占用资源。
3、反馈结果:各参与者执行完,向协调者发送Ack消息
4、完成事务:协调者收到所有的参与者的反馈Ack消息后,完成事务。
中断事务:任意参与者返回no,或等待超时
1、中断请求:协调者向参与者节点发送abort请求
2、事务回滚:参与者收到abort请求后,会利用其在第二阶段中记录的Undo信息来执行事务回滚操作。并释放占用资源。
3、反馈结果:完成回滚后发送Ack消息
4、中断事务:接收到所有的参与者的Ack消息后,中断事务。
注意: 进入第三阶段会存在两种故障
1、协调者出现问题
2、协调者和参与者之间网络出现问题
无论出现那种情况,最终都会导致参与者无法及时收到来自协调者的doCommit或abort请求。对于这种情况,参与者都会在等待超时后,继续进行事务的提交。
三阶段提交优点:
相较于二阶段提交,三阶段降低了参与者的阻塞范围,并且能在出现单点故障后继续打成一致。
三阶段提交缺点:
去除阻塞的同时,也引入新的问题,那就是在参与者接收到PreCommit请求后,如果网络出现分区,测试协调者和参与者无法通信。参与者依然会提交事务,导致数据不一致。