我想编写一些代码来检测死锁,如果发生死锁,请重试 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;
}
}
为什么这种重试逻辑会在重试之间包含这样的时间延迟?
答案 0 :(得分:1)
没有延迟,死锁重试可能会“响应”网络/磁盘/数据库的活动,直到循环停止。最好在循环中放置一个小延迟,允许其他流量首先通过(实际上可能需要解决死锁),然后再次尝试。
答案 1 :(得分:1)
等待没有必要取得进展。幸存的冲突事务可能被授予冲突事务所争论的锁定。
另一方面,另一个交易可能仍然活跃,可能正在做类似的事情。可能会出现另一个僵局。在一小段延迟之后,其他交易可能是其中一个或正在做其他事情。
重试在第二次尝试中更有可能成功。这不是正确性所必需的。