[英]Resubmit transaction after deadlock
我有一个包含在事务范围内的代码块。 我正在使用LINQ与数据库进行通信。 捕获死锁异常后,如何重新提交事务?
基本上,您只是捕获死锁异常并再次尝试代码。 我们做这样的事情:
private static void ExecuteWithDeadlockRetry(int maxAttempts, bool useTransaction, Action action)
{
int tryCount = 0;
string errorMessage;
// If use transaction is true and there is an existing ambient transaction (means we're in a transaction already)
// then it will not do any good to attempt any retries, so set max retry limit to 1.
if (useTransaction && Transaction.Current != null) { maxAttempts = 1; }
do
{
try
{
// increment the try count...
tryCount++;
if (useTransaction)
{
// execute the action inside a transaction...
using (TransactionScope transactionScope = new TransactionScope())
{
action();
transactionScope.Complete();
}
}
else
action();
// If here, execution was successful, so we can return...
return;
}
catch (SqlException sqlException)
{
if (sqlException.Number == (int)SqlExceptionNumber.Deadlock && tryCount < maxAttempts)
{
// Log error here
}
else
{
throw;
}
}
} while (tryCount <= maxAttempts);
}
电话看起来像这样:
SqlDeadlockHelper.Execute(() =>
{
// Code to execute here
}
请注意,Execute()方法最终调用ExecuteWithDeadlockRetry()。 我们的解决方案比您要求的要多一些,但这应该给您一些总体方向。
首先想一想为什么会发生僵局? 是因为您在LINQ上下文中读取的值和已修改的值是否被另一个事务更改 ? 唯一合理的操作是再次读取值并确定您的更改是否对新值有意义 。 由于这是ASP.NET,这意味着显示使用的新值,因此您必须再次将页面返回给用户,并注意发生了更改,并且必须再次编辑数据。
在僵局自动重新提交是可能的,但几乎总是是一个坏主意。 它可能会导致数据库中的状态错误,因为您的域规则被破坏,因为重试会覆盖读取值后发生的更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.