簡體   English   中英

死鎖后重新提交事務

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM