分布式事物之三阶段事物提交

三阶段提交协议(3PC:Three-Phrase Commit)

  针对两阶段提交存在的问题,三阶段提交协议通过引入一个“预询盘”阶段,以及超时策略来减少整个集群的阻塞时间,提升系统性能。三阶段提交的三个阶段分别为:can_commit,pre_commit,do_commit。

第一阶段:can_commit

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

     1. 协调者向各个参与者发送事务询问通知,询问是否可以执行事务操作,并等待回复
     2. 各个参与者依据自身状况回复一个预估值,如果预估自己能够正常执行事务就返回确定信息,并进入预备状态,否则返回否定信息

第二阶段:pre_commit

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

  1. 所有的参与者都返回确定信息
  2. 一个或多个参与者返回否定信息
  3. 协调者等待超时

针对第一种情况,协调者会向所有参与者发送事务执行请求,具体步骤如下:

  1. 协调者向所有的事务参与者发送事务执行通知
  2. 参与者收到通知后,执行事务,但不提交
  3. 参与者将事务执行情况返回给客户端

在上面的步骤中,如果参与者等待超时,则会中断事务。 针对第二、三种情况,协调者认为事务无法正常执行,于是向各个参与者发出abort通知,请求退出预备状态,具体步骤如下:

  1. 协调者向所有事务参与者发送abort通知
  2. 参与者收到通知后,中断事务

 

 

第三阶段:do_commit

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

  1. 所有的参与者都能正常执行事务
  2. 一个或多个参与者执行事务失败
  3. 协调者等待超时

针对第一种情况,协调者向各个参与者发起事务提交请求,具体步骤如下:

  1. 协调者向所有参与者发送事务commit通知
  2. 所有参与者在收到通知之后执行commit操作,并释放占有的资源
  3. 参与者向协调者反馈事务提交结果

 

 针对第二、三种情况,协调者认为事务无法正常执行,于是向各个参与者发送事务回滚请求,具体步骤如下:

  1. 协调者向所有参与者发送事务rollback通知
  2. 所有参与者在收到通知之后执行rollback操作,并释放占有的资源
  3. 参与者向协调者反馈事务提交结果

 

 

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

  在分布式数据库中,如果期望达到数据的强一致性,那么服务基本没有可用性可言,这也是为什么许多分布式数据库提供了跨库事务,但也只是个摆设的原因,在实际应用中我们更多追求的是数据的弱一致性或最终一致性,为了强一致性而丢弃可用性是不可取的。

 

posted @ 2021-12-23 10:45  IT6889  阅读(247)  评论(0编辑  收藏  举报