三阶段提交(3PC)是二阶段提交(2PC)的改良版本,三阶段提交协定次要是为了解决两阶段提交协定的阻塞问题,2pc存在的问题是当协调者解体时,参与者不能做出最初的抉择。因而参与者可能在协调者复原之前放弃阻塞。三阶段提交(Three-phase commit),是二阶段提交(2PC)的改良版本。

三阶段提交3PC

与两阶段提交不同的是,三阶段提交有两个改变点:

  • 引入超时机制。同时在协调者和参与者中都引入超时机制;
  • 在第一阶段和第二阶段中插入一个筹备阶段。保障了在最初提交阶段之前各参加节点的状态是统一的。

3PC把2PC的筹备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。

CanCommit阶段

之前2PC的一阶段是本地事务执行完结后,最初不Commit,等其它服务都执行完结并返回Yes,由协调者产生commit才真正执行commit。而这里的CanCommit指的是 尝试获取数据库锁 如果能够,就返回Yes。这阶段次要分为2步

  • 事务询问:协调者向参与者发送CanCommit申请。询问是否能够执行事务提交操作。而后开始期待参与者的响应;
  • 响应反馈:参与者接到CanCommit申请之后,失常状况下,如果其本身认为能够顺利执行事务,则返回Yes响应,并进入准备状态。否则反馈No。

PreCommit阶段

在阶段一中,如果所有的参与者都返回Yes的话,那么就会进入PreCommit阶段进行事务预提交。这里的PreCommit阶段 跟下面的第一阶段是差不多的,只不过这里协调者和参与者都引入了超时机制 (2PC中只有协调者能够超时,参与者没有超时机制),次要蕴含两个步骤:

  • 事务预提交:参与者接管到PreCommit申请后,会执行事务操作,并将undo和redo信息记录到事务日志中。
  • 响应反馈:如果参与者胜利的执行了事务操作,则返回ACK响应,同时开始期待最终指令。

如果有任何一个参与者向协调者发送了No响应,或者期待超时之后,协调者都没有接到参与者的响应,那么就执行事务的中断:

  • 发送中断请求:协调者向所有参与者发送abort申请。
  • 中断事务:参与者收到来自协调者的abort申请之后(或超时之后,仍未收到协调者的申请),执行事务的中断。

DoCommit阶段

该阶段进行真正的事务提交,也能够分为以下两种状况。

执行提交,发送提交申请 协调接管到参与者发送的ACK响应,那么他将从预提交状态进入到提交状态。并向所有参与者发送doCommit申请。

  • 事务提交:参与者接管到doCommit申请之后,执行正式的事务提交。并在实现事务提交之后开释所有事务资源。
  • 响应反馈:事务提交完之后,向协调者发送Ack响应。
  • 实现事务:协调者接管到所有参与者的ack响应之后,实现事务。

中断事务,协调者没有接管到参与者发送的ACK响应(可能是接受者发送的不是ACK响应,也可能响应超时),那么就会执行中断事务。

  • 发送中断请求:协调者向所有参与者发送abort申请
  • 事务回滚:参与者接管到abort申请之后,利用其在阶段二记录的undo信息来执行事务的回滚操作,并在实现回滚之后开释所有的事务资源。
  • 反馈后果:参与者实现事务回滚之后,向协调者发送ACK音讯
  • 中断事务:协调者接管到参与者反馈的ACK音讯之后,执行事务的中断。

总结

绝对于2PC,3PC次要解决的单点故障问题,并缩小阻塞,因为一旦参与者无奈及时收到来自协调者的信息之后,他会默认执行commit。而不会始终持有事务资源并处于阻塞状态。然而这种机制也会导致数据一致性问题,因为,因为网络起因,协调者发送的abort响应没有及时被参与者接管到,那么参与者在期待超时之后执行了commit操作。这样就和其余接到abort命令并执行回滚的参与者之间存在数据不统一的状况。

在2PC中一个参与者的状态只有它本人和协调者通晓,如果协调者提议后本身宕机,在协调者备份启用前一个参与者又宕机,其余参与者就会进入既不能回滚、又不能强制commit的阻塞状态,直到参与者宕机复原。

参与者如果在不同阶段宕机,咱们来看看3PC如何应答:

  • 阶段1: 协调者或协调者备份未收到宕机参与者的vote,间接停止事务;宕机的参与者复原后,读取logging发现未收回赞成vote,自行停止该次事务
  • 阶段2: 协调者未收到宕机参与者的precommit ACK,但因为之前曾经收到了宕机参与者的赞成反馈(不然也不会进入到阶段2),协调者进行commit;协调者备份能够通过问询其余参与者取得这些信息,过程同理;宕机的参与者复原后发现收到precommit或曾经收回赞成vote,则自行commit该次事务
  • 阶段3: 即使协调者或协调者备份未收到宕机参与者t的commit ACK,也完结该次事务;宕机的参与者复原后发现收到commit或者precommit,也将自行commit该次事务。

我是御狐神,欢送大家关注我的微信公众号:wzm2zsd

本文最先公布至微信公众号,版权所有,禁止转载!