can you safely re

I am using TransactionScope in the following fashion

using (var scope = new TransactionScope())
{
    using (var conn = SQLHelpers.GetSQLConnection())
    {  
          //commands here
    }
    scope.Complete();
}

Sometimes I am getting an TransactionAbortedException when calling scope.Complete() as the transaction has already been rolled back and I have used the profiler to determine the issue is a deadlock.

Exception Transaction (Process ID 59) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

I've since found the cause for the deadlock however it got me wondering why this error did not bubble up to the TransactionAbortedException so I could indeed re-run the transaction just for that specific case. The inner exception(s) did NOT contain any information that could indicate what the actual error was.

Is it safe to detect a TransactionAbortedException as the reason to re-run the transaction?

Up to now I've seen the following inner exceptions:

1) deadlock
2) timeout
3) 'connection was closed'
4) .. other ?

in only 1 of these cases it seems appropriate to re-run the transaction however you could generalize this to all cases if you were guaranteed a rollback. The question could be re-stated to ask 'does a TransactionAbortedException guarantee the transaction was rolled back' ?


The question could be re-stated to ask 'does a TransactionAbortedException guarantee the transaction was rolled back'?

The documentation for TransactionAbortedException says:

This exception is thrown when an action is attempted on a transaction that has already been rolled back , for example, when you attempt to call the Commit method on a transaction that has already timed out. This exception is also thrown when an attempt is made to commit the transaction and the transaction aborts.

This is a recoverable error.

I think it is pretty clear from this description that if you catch this exception, your transaction didn't complete successfully due to some reason. My understanding of the docs is: "Whatever changes the transaction was trying to do were not committed to the database".

"This is a recoverable error", so if the nature of your transaction is such that it makes sense to retry it, then you should retry it after catching this exception.

You may want to introduce some logic around retries, such as waiting for some time before retry. And increase this waiting time as the number of retry attempts increases. Have a limit on the total amount of retries or total retry time and do something sensible/fail gracefully when all attempts to retry failed.

链接地址: http://www.djcxy.com/p/36894.html

上一篇: 强制Angular2在导航时重新加载组件

下一篇: 你可以安心吗?