【问题标题】:Resubmit transaction after deadlock死锁后重新提交事务
【发布时间】:2012-08-31 23:14:14
【问题描述】:

我有一个封装在事务范围内的代码块。我正在使用 LINQ 与数据库进行通信。捕获到死锁异常后,如何重新提交事务?

【问题讨论】:

  • 你为什么使用事务范围。你有多个提交更改吗? 9/10 次这是没有必要的。

标签: c# asp.net .net sql-server linq-to-sql


【解决方案1】:

基本上,您只需捕获死锁异常并再次尝试代码。我们这样做:

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()。我们的解决方案比您所要求的要多一些,但这应该会给您一些大致的方向。

【讨论】:

【解决方案2】:

首先考虑为什么会发生死锁?是因为您在 LINQ 上下文中读取并修改的值已被另一个事务更改?唯一合理的做法是再次读取值并确定您的更改对新值是否有意义。由于这是 ASP.NET,这意味着向用户显示新值,因此您必须再次将页面返回给用户,并通知用户发生了更改并且必须再次编辑数据。

在死锁时自动重新提交可能的,但几乎总是一个坏主意。这可能会导致数据库中的错误状态,因为您的域规则被破坏,因为您的重试会覆盖在读取值之后发生的更改

【讨论】:

    猜你喜欢
    • 2020-02-27
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多