分布式理论:一致性协议 3PC

1. 三阶段提交介绍

3PC,全称 “three phase commit”,是 2PC 的改进版,将 2PC 的 “提交事务请求” 过程一分为二,共造成了由CanCommit、PreCommit和doCommit三个阶段组成的事务处理协议。
web

2. 阶段一 :CanCommit

  • 事务询问
    协调者向全部的参与者发送一个包含事务内容的canCommit请求,询问是否能够执行事务提交操做,并开始等待各参与者的响应。
  • 各参与者向协调者反馈事务询问的响应
    参与者在接收到来自协调者的包含了事务内容的canCommit请求后,正常状况下,若是自身认为能够顺利执行事务,则反馈Yes响应,并进入预备状态,不然反馈No响应。
    在这里插入图片描述

3. 阶段二:PreCommit

协调者在获得全部参与者的响应以后,会根据结果有2种执行操做的状况:执行事务预提交,或者中断事务
假如全部参与反馈的都是Yes,那么就会执行事务预提交。网络

  • 执行事务预提交分为 3 个步骤
    • 发送预提交请求:
      协调者向全部参与者节点发出preCommit请求,并进入prepared阶段。
    • 事务预提交:
      参与者接收到preCommit请求后,会执行事务操做,并将Undo和Redo信息记录到事务日志中。
    • 各参与者向协调者反馈事务执行的结果:
      若参与者成功执行了事务操做,那么反馈Ack

若任一参与者反馈了No响应,或者在等待超时后,协调者尚没法接收到全部参与者反馈,则中断事务svg

  • 中断事务也分为2个步骤
    • 发送中断请求:
      协调者向全部参与者发出abort请求。
    • 中断事务:
      不管是收到来自协调者的abort请求或者等待协调者请求过程当中超时,参与者都会中断事务

4. 阶段三:doCommit


该阶段作真正的事务提交或者完成事务回滚,因此就会出现两种状况:设计

第一种状况:执行事务提交日志

  1. 发送提交请求:
    进入这一阶段,假设协调者处于正常工做状态,而且它接收到了来自全部参与者的Ack响应,那么他将从预提交状态转化为提交状态,并向全部的参与者发送doCommit请求。
  2. 事务提交:
    参与者接收到doCommit请求后,会正式执行事务提交操做,并在完成提交以后释放整个事务执行过程当中占用的事务资源。
  3. 反馈事务提交结果:
    参与者在完成事务提交后,向协调者发送Ack响应。
  4. 完成事务:
    协调者接收到全部参与者反馈的Ack消息后,完成事务。

第二种状况:中断事务code

  1. 发送中断请求:协调者向全部的参与者节点发送abort请求。
  2. 事务回滚:参与者收到abort请求后,会根据记录的Undo信息来执行事务回滚,并在完成回滚以后释放整
    个事务执行期间占用的资源。
  3. 反馈事务回滚结果:参与者在完成事务回滚后,向协调者发送Ack消息。
  4. 中断事务:协调者接收到全部参与者反馈的Ack消息后,中断事务。

注意:一旦进入阶段三,可能会出现 2 种故障:xml

  1. 协调者出现问题
  2. 协调者和参与者之间的网络故障

若是出现了任一一种状况,最终都会致使参与者没法收到 doCommit 请求或者 abort 请求,针对这种状况,参与者都会在等待超时以后,继续进行事务提交blog

5. 2PC对比3PC

  • 首先对于协调者和参与者都设置了超时机制(在2PC中,只有协调者拥有超时机制,即若是在必定时间内没有收到参与者的消息则默认失败),主要是避免了参与者在长时间没法与协调者节点通信(协调者挂掉了)的状况下,没法释放资源的问题,由于参与者自身拥有超时机制会在超时后,自动进行本地commit从而进行释放资源。而这种机制也侧面下降了整个事务的阻塞时间和范围。three

  • 经过CanCommit、PreCommit、DoCommit三个阶段的设计,相较于2PC而言,多设置了一个缓冲阶段保证了在最后提交阶段以前各参与节点的状态是一致的 。图片

  • PreCommit是一个缓冲,保证了在最后提交阶段以前各参与节点的状态是一致的。

注意:3PC协议并无彻底解决数据不一致问题。