死锁后,为什么应用程序代码要等待重试



我想编写一些代码来检测死锁,如果发生死锁,请重试尝试的任何数据库操作,最多 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;
    }
}

为什么此类重试逻辑应包括重试之间的时间延迟?

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

等待不是取得进展的必要条件。幸存下来的冲突事务可能被授予了冲突事务所争用的锁。

另一方面,另一个事务可能仍然处于活动状态,并且可能正在做类似的事情。另一个僵局是可能的。经过一小段延迟后,其他事务可能是一个或现在正在做其他事情。

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

最新更新