二阶段提交

why:

  栗子:假设一个人要从 A 银行向 B 银行进行跨行转账 100 元。

  希望:两个操作( -100 和 + 100),它们是一个事务, 要么同时成功, 要么同时失败 。即:原子性的提交协议(Atomic Commit Protocol)

 

what:

  原子性提交协议(有2个特征):

    安全性:任意一方 commit, 所有人必须都 commit;任意一方中断,则所有人都不 commit

    存活性:没有宕机或失败发生时, A 和 B 都能提交则提交;发生失败时,能够最终一致性结果(成功/失败), 予以响应, 不能一直等待

 

  二阶段提交协议

      

 

    

 

    上述流程的核心点:

      当 TC 收到 A 和 B 响应 “Yes” 后, 做出了 “commit” 的决定, 向 A /B 发送指令, 并不需要再等待 A/B 的响应, 可以直接向 client 返回成功。

    操作的保证点:当 A/B 返回 Yes 后, 就代表 A 和 B 都做好了提交准备, 只要 TC 决定要提交,即使 A/B 宕机, 没有收到 TC 的 Commit 指令, 只要 A/B 被修复重启, A 和 B 都必须有能力成功完成提交操作。

 

  二阶段提交的安全性

    协调者 TC,作为一个中心, 统一收集了 A 和 B 是否有意愿(有能力)进行 commit;

    协调者 TC 强制保证了, A, B 双方必须都有意愿提交时, 才进行 commit;

 

  二阶段提交的存活性:

    注意:协议无法满足存活性。

    可能面临哪些问题:

      a、响应超时。 可能原因:其他结点故障了;网络情况不好, 数据包丢失了或网络干脆中断了;

      b、重启。节点宕机, 重启以后, 如何恢复被中断的操作;

 

    等带响应超时应对

      1、TC 需要等待 A 和 B 返回 “yes”/“no” 超时:

                    

        对策:采取了非常保守的方案。

          此时TC 还没有发送过任何 “commit” 指令,则此时TC可以安全地发起终止 “abort” 指令, 放弃 commit。

 

      2、A 和 B 需要等待 TC 发送 “commit”/ “abort” 指令, 才能进行下一步操作(等待):

             

 

 

        对策:B 为例进行考虑( A 的情形完全对称)

          a、如果 B 之前回复的是 “no” , 那此时, B 直接abort。 因为 TC 即使收到了响应,也是“abort”;

          b、B 之前回复了 “Yes”,则不能“abort”,也不能commit。因为A可能也yes了,并且A收到commit,只是B没收到,而应该commit;或者A回复了NO,而应该abort。

            对策:B针对这种情形发起一轮终止协议操作(Termination Protocol)

        

 

         超时终止协议

           B向A咨询

            B没有响应:则B只能等待(TC恢复,再查询TC);

            A收到“commit”/ “abort” 指令:B跟随;

            A没回复 “yes”/“no”:A、B直接abort。(TC超时后,也会下发abort);

            A回复NO:A、B直接abort;

            A回复yes:B则只能等TC信(TC恢复,再查询TC);(原因:A 和 B 可能都 “Yes”,只是A、B没收到,但是也就OK于client;TC可能等待超时,只是abort没到 )

 

       宕机重启应对

        基本原则: 一旦 TC 决定了 commit , 那么任意一个结点都不允许发生回滚

 

        方案:所有的结点, 都能知道他们在宕机前的状态是什么, 那就有如下几种解决方案:

          a、A 或 B 相互发起之前描述的终止协议 Termination Protocol, 即相互询问是否知道事务已经交;

          b、A 和 B 也可以向 TC 发起状态查询操作, TC 可能知道事务是否已经提交;

 

        具体措施:所有节点发送任何信息给其他结点, 一定要先行将自己要回复的内容写入磁盘

           TC 而言, 在向 A 和 B 发送 “commit” 指令前, 一定要先行将 “commit” 成功记录到磁盘;

           A/B 而言, 在向 TC 发送 “yes” 之前, 一定要先行将 “yes” 记录成功记录到磁盘;

 

        重启之后就可以进行如下的操作:

          a、对于TC, 重启以后, 如果发现磁盘中没有记录 “commit” , 那就可以直接进行 “abort” 操作;

          b、 A 或者 B , 重启以后, 如果发现磁盘中没有记录 “yes” , 那就可以直接进行 “abort” 操作;

          c、A或者 B, 重启以后, 如果发现磁盘中有 “yes” 记录, 那就可以发起终止协议 “termination protocol”;

          d、TC, A, B 都发生了重启操作, 只要当 3 个结点都恢复以后, 就可以向 TC 发起查询, 查看TC 的磁盘中是否存在 “commit” 记录, 如果存在, 则均可进行 “commit” 操作。

 

      

posted @ 2022-03-17 23:46  修心而结网  阅读(126)  评论(0编辑  收藏  举报