【问题标题】:Could I just always flush a write ahead log instead of implementing a Two-Phase Commit protocol?我可以总是刷新一个预写日志而不是实现一个两阶段提交协议吗?
【发布时间】:2020-09-08 02:21:29
【问题描述】:

我无法理解two-phase commit protocol 的部分内容。我完全不明白第二阶段有什么帮助。

据我了解,第二个(完成)阶段可能会失败,就像我们只有一个阶段一样。我们是否需要第二阶段来确保在刷新预写日志时捕获磁盘故障?如果是这样,是否需要不断刷新预写日志并避免缓慢的网络通信和延迟?

【问题讨论】:

    标签: database transactions commit distributed-computing distributed-transactions


    【解决方案1】:

    两阶段提交协议是跨多个不同实体的事务。

    考虑一个例子 姓名:用户 1,余额:100 美元 姓名:User2,余额:$200

    现在假设在一笔交易中,您将 50 美元从用户 1 转移到用户 2。现在交易余额应该变成了

    姓名:User1,余额:50 美元

    姓名:User2,余额:250 美元


    因此有两个步骤

    void Transaction(int amount)
    {
      User2.Add(amount);
      User1.Subtract(amount);
    }
    

    现在如果金额为 150 美元,在这种情况下 User1.Subtract(amount) 将失败(因为余额不能为负数),而 User2.Add(amount) 会成功。

    要执行各种验证,需要“投票”阶段。 “提交”阶段存在以原子方式说是/否来完成事务。两相的非常简单的伪代码是:

    bool Perform_Two_Phase_Transaction(int amount)
    {
      var addVote = User2.VoteFor_Add(amount);
      var subtractVote = User1.VoteFor_Subtract(amount);
      if(addVote && subtractVote)
      {
        var addCommit = User2.Commit();
        var subtractCommit = User1.Commit();
        if(addCommit && subtractCommit)
        {
          return true;
        }
        if(addCommit)
        {
          User2.Rollback();
          return false;
        }
        if(subtractCommit)
        {
          User1.Rollback();
          return false;
        }
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 2020-02-29
      • 2012-07-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多