首页 > 解决方案 > 我可以总是刷新一个预写日志而不是实现一个两阶段提交协议吗?

问题描述

我无法理解两阶段提交协议的部分内容。我不明白第二阶段有什么帮助。

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

标签: databasetransactionscommitdistributed-computingdistributed-transactions

解决方案


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

考虑一个示例 名称:用户 1,余额:100 美元 名称:用户 2,余额:200 美元

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

姓名:用户 1,余额: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;
    }
  }
}

推荐阅读