一致性协议

2PC和3PC

2PC(Two-Phare Commit)

阶段一:提交事务请求

  1 - 事务询问  协调者像所有参与者发送事务内容,询问是否可以执行事务提交操作,并开始等待各参与者的响应。

  2 - 执行事务  各参与者执行事务,并记录Undo和Redo信息(Undo和Redo是数据库用来commit和rollback的记录文件)

  3 - 各参与者向协调者反馈事务询问的响应  如果参与者事务执行成功,则返回给协调者yes,否则返回给协调者no

阶段二:执行事务提交

  1 - 执行事务提交(所有的参与者均返回yes)

    1 - 发送提交请求  协调者向所有参与者发送提交请求

    2 - 事务提交  参与者接收到协调者发出的请求后,完成自己的事务提交,并在提交完成后释放这个事务执行期间占据的资源

    3 - 反馈事务提交结果  参与者在完成事务后,像协调者发送Ack消息

    4 - 完成事务  协调者接收到所有参与者返回的Ack消息,完成整个分布式事务

  2 - 执行事务回滚(非所有参与者均返回yes)

    1 - 发送回滚请求  协调者向所有参与者发送rollback请求

    2 - 事务回滚  参与者接收到协调者发出的请求后,完成自己的事务回滚,并在提交完成后释放这个事务执行期间占据的资源

    3 - 反馈事务回滚结果  参与者在完成各自的事务回滚后,向协调者发送Ack消息

    4 - 中断事务(回滚事务)  协调者接收到所有参与者返回的Ack消息后,完成分布式事务的回滚

 

2PC的优缺点

优点:原理简单,实现方便

缺点:同步阻塞,单点问题,脑裂,数据不一致,太过保守

 

3PC(Three-Phare Commit)

阶段一(CanCommit):

  1 - 事务询问:协调者询问各参与者是否可以开始事务,并开始恩待各参与者的响应

  2 - 各参与者回复协调者反馈事务询问的请求:参与者如果可以执行事务,返回yes,否则返回no

阶段二(PreCommit)

  1 - 执行事务预提交:所有参与者均返回yes

    1 - 发送预提交请求:协调者向所有参与者发出preCommit请求,并进入Prepared阶段

    2 - 事务预提交:参与者接到preCommit请求后,会执行当前事务,并记录Undo和Redo信息

    3 - 各参与者向协调者反馈事务预提交的情况:如果参与者成功执行了事务操作,那么就会返回给协调者Ack响应

  2 - 中断事务(分布式事务回滚)

    1 - 发送中断请求:协调者向所有的参与者发送abort请求

    2 - 中断事务:无论是收到来自协调者的abort请求,或者是在等待协调者请求过程中出现超时,参与者都会中断事务

阶段三(doCommit)

  1 - 执行提交

    1 - 发送提交请求:协调者接收到了所有参与者在阶段二返回的Ack响应,那么它将会从"预提交"状态变成"提交"状态,并向所有的参与者发送doCommit请求

    2 - 事务提交:参与者接收到协调者发出的doCommit请求后,会将自己的事务正式提交,并在完成之后释放整个事务执行期间占用的事务资源

    3 - 反馈事务提交结果:各参与者将自己的事务提交后,会向协调者发送Ack消息

    4 - 完成事务:协调者接收到所有参与者反馈的Ack消息后,完成事务

  2 - 中断事务()

    1 - 协调者发送中断请求:协调者向所有的参与者发送abort请求

    2 - 事务回滚:参与者在接收到协调者发出的abort请求后,会利用之前记录的Undo信息执行事务回滚,并在成功回滚后释放事务执行期间占用的资源

    3 - 返回事务回滚结果:参与者在完成事务回滚后,向协调者发送Ack消息

    4 - 中断事务:协调者在接收到所有参与者返回的Ack消息后,中断事务。

当协调者出现问题

或者参与者和协调者直接的网络出现问题

无论哪种情况,都会导致参与者无法及时接受到来自协调者发送的doCommit请求或者abort请求,针对这样的情况,参与者会在等待超时之后,继续进行事务提交。

 

优缺点:

1 - 相对于2PC,降低了参与者的阻塞范围,因为有阶段一。在阶段一就能确定是否可以执行事务。当部分参与者在阶段一表示无法正常开启事务时,是不会让其他参与者阻塞的,而不是像2PC那样上来直接开启事务,让所有参与者都处于阻塞状态

2 - 在单点故障后还能达成一致。引入超时处理,当单点故障后,参与者会自己回滚

 

缺点:

在协调者向所有参与者发送doCommit请求时,协调者和部分参与者之间的网络出现问题,导致部分参与者接收到doCommit请求,部分参与者没有接收到。接收到doCommit请求的参与者完成了自己的事务,没有接收到doCommit请求的参与者在超时之后将之前预提交的事务回滚,从而导致整个系统的数据不一致。

 

 

 

 

posted @ 2019-10-17 17:18  极速战略J  阅读(140)  评论(0编辑  收藏  举报