简体   繁体   中英

Resubmit transaction after deadlock

I have a block of code wrapped in a transaction scope. I'm using LINQ to communicate with the database. Once I capture a deadlock exception, how do I resubmit the transaction?

Basically, you just catch the deadlock exception and try the code again. We do something like this:

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);
}

And the call looks like this:

SqlDeadlockHelper.Execute(() =>
{
  // Code to execute here
}

Note that the Execute() method eventually calls ExecuteWithDeadlockRetry(). There is a bit more to our solution than what you're asking, but this should give you some general direction.

Think first and foremost why did the deadlock happen? Is it because a value you've read in you LINQ context and modified was changed by another transaction ? The only reasonable action is to read again the values and decide if your changes make any sense with the new values . Since this is ASP.NET, this implies showing the new values to the use, so you must return again the page to the user with a notice that a change occurred and it has to edit the data again.

Automatic resubmit on deadlock is possible, but almost always is a bad idea. It will likely result in bad state in the database because your domain rules are broken as your retry overwrites changes that occurred after the value was read.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM