上一篇:《分布式之事务解决方案》 我们对于分布式事务解决方案有了一个汇总,分布式事务产生的原因,其解决方案。上一篇还有很多知识点没有讲到,比如二段提交,三段提交等。今天我们来一起探索一下分布式事务之二段提交三段提交算法。
本文主要对以下问题进行介绍:
在分布式系统中,各个物理节点相互独立,通过网络沟通协调。在关系型数据库中,存在事务机制,可以保证各个单节点的ACID。但是在分布式情况下,相互独立节点无法知道其他节点执行事务的情况。所以出现了一些解决这个问题的方案。
二段提交与三段提交是分布式事务一致性的经典算法。下面来介绍一下二段提交。
在分布式事务的定义中,如果想让分布式部署的多台机器中的数据保持一致性,那么就要保证在所有节点的数据写操作,要么全部都执行,要么全部都不执行。但是,一台机器在执行本地事务的时候无法知道其他机器中本地事务的执行结果,节点并不知道本次事务到底应该 Commit 还是 Rollback。
在前面介绍过的几种一致性算法中,都是通过一个Leader进程进行协调,在2PC(两阶段)和3PC(三阶段)中也是一样的解决办法。二阶段和三阶段提交协议都是引入了一个协调者的组件来统一调度所有分布式节点的执行,让当前节点知道其他节点的任务执行状态,通过通知和表决的方式,决定执行 Commit 还是 Rollback 操作。
两阶段提交中的两个阶段,指的是 「Commit-request 阶段」 和 「Commit 阶段」 ,两阶段提交的流程如下:
在提交请求阶段,协调者将通知事务参与者准备提交事务,然后进入表决过程。在表决过程中,参与者将告知协调者自己的决策:同意(事务参与者本地事务执行成功)或取消(本地事务执行故障),在第一阶段,参与节点并没有进行Commit操作。
在提交阶段,协调者将基于第一个阶段的投票结果进行决策:提交或取消这个事务。这个结果的处理和前面基于半数以上投票的一致性算法不同,必须当且仅当所有的参与者同意提交,协调者才会通知各个参与者提交事务,否则协调者将通知各个参与者取消事务。
参与者在接收到协调者发来的消息后将执行对应的操作,也就是本地 Commit 或者 Rollback。
如上图可以知道一下缺陷:
为了解决二阶段协议中的同步阻塞等问题,三阶段提交协议在协调者和参与者中都引入了超时机制,并且把两阶段提交协议的第一个阶段拆分成了两步:询问,然后再锁资源,最后真正提交。
三阶段中的 Three Phase 分别为 「CanCommit」、「PreCommit」、「DoCommit」 阶段。
3PC 的 CanCommit 阶段其实和 2PC 的准备阶段很像。协调者向参与者发送 Commit 请求,参与者如果可以提交就返回 Yes 响应,否则返回 No 响应。
这一阶段分为两种情况:
1、协调者收到了所有参与者的响应---都是YES 那么就进入下一阶段
2、协调者没有(超时等情况) 或者收到一个参与者响应--NO ,那么中断事务
这一阶段分为三种情况:
1、协调者收到所有参与者响应,「提交事务」
2、协调者没有接收到参与者的响应,超时或者其他情况。 「中断事务」
3、参与者没有收到协调者的响应,超时或者其他情况。「提交事务」