【问题标题】:After a deadlock, why should application code wait before retrying?死锁后,为什么应用程序代码要等待再重试?
【发布时间】:2013-10-03 05:45:17
【问题描述】:

我想编写一些代码来检测死锁,如果发生死锁,请重试尝试的任何数据库操作,最多 n 次。我注意到人们经常在重试之间添加时间延迟。下面是一些 C# 代码来阐明我的意思:

void RetryIfDeadlocks(Action dbOperation, int maximumRetries)
{
    try
    {
        dbOperation();
    }
    catch (DeadlockException)
    {
        var shouldRetry = maximumRetries > 0;

        if (shouldRetry)
        {
            Task.Delay(millisecondsDelay: 300).Wait();
            RetryIfDeadlocks(dbOperation, maximumRetries - 1);
        }
        else
            throw;
    }
}

为什么这样的重试逻辑要在重试之间包含这样的时间延迟?

【问题讨论】:

  • Task.Delay(millisecondsDelay: 300).Wait() 那是一架竹子货机,还是说这样做比睡觉有好处?
  • @Will,我不确定Task.Delay 是否优于Thread.Sleep。在我写这个问题的时候,我可能认为Task.Delay 没有人们与Thread.Sleep 关联的一些问题。还有什么是竹货机?
  • en.wikipedia.org/wiki/Cargo_cult_programming Task.Delay 在使用 async/await 时更胜一筹,绝对...

标签: sql deadlock database-deadlocks


【解决方案1】:

如果没有延迟,死锁重试可能会“猛击”网络/磁盘/数据库的活动,直到循环停止。最好在循环中放置一点延迟,让其他流量先通过(实际上这可能是解决死锁所必需的),然后再试一次。

【讨论】:

    【解决方案2】:

    没有必要等待才能取得进展。幸存的冲突事务很可能被授予了冲突事务争用的锁。

    另一方面,另一个事务可能仍处于活动状态,并且可能正在做类似的事情。可能还会出现另一个僵局。稍作延迟后,其他交易可能是一个或正在做其他事情。

    重试使第二次尝试成功的可能性更大。它不是正确性所必需的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-02-24
      相关资源
      最近更新 更多