Even if the transaction is local, transaction will still escalated to the MSDTC if you open multiple connections within the same transaction scope, according to this article: http://msdn.microsoft.com/en-us/library/ms229978(v=vs.110).aspx
An escalation that results in the System.Transactions infrastructure transferring the ownership of the transaction to MSDTC happens when: ...
- At least two durable resources that support single-phase notifications are enlisted in the transaction. For example, enlisting a single connection with does not cause a transaction to be promoted. However, whenever you open a second connection to a database causing the database to enlist, the System.Transactions infrastructure detects that it is the second durable resource in the transaction, and escalates it to an MSDTC transaction.
NOTE: I have read some articles that state that this only applies to SQL 2005, and that SQL 2008+ is smarter about the MSDTC promotion. These state that SQL 2008 will only promote to MSDTC when multiple connections are open at the same time. See: TransactionScope automatically escalating to MSDTC on some machines?
Also, your inner exception is a Timeout
(System.Data.SqlClient.SqlException: Timeout expired), not a Deadlock
. While both are related to blocking, they are not the same thing. A timeout
occurs when blocking causes the application to stop waiting on a resource that is blocked by another connection, so that the current statement can obtain locks on that resource. A deadlock
occurs when two different connections are competing for the same resources, and they are blocking in a way they will never be able to complete unless one of the connections is terminated (this why the deadlock error messages say "transaction... has been chosen as the deadlock victim"). Since your error was a Timeout, this explains why you deadlock query returned a 0 count.
System.Transactions.TransactionInDoubtException
from MSDN (http://msdn.microsoft.com/en-us/library/system.transactions.transactionindoubtexception(v=vs.110).aspx) states:
This exception is thrown when an action is attempted on a transaction that is in doubt. A transaction is in doubt when the state of the transaction cannot be determined. Specifically, the final outcome of the transaction, whether it commits or aborts, is never known for this transaction.
This exception is also thrown when an attempt is made to commit the transaction and the transaction becomes InDoubt.
The reason: something occurred during the TransactionScope
that caused it's state to be unknown at the end of the transaction.
The cause: There could be a number of different causes, but it is tough to identify your specific cause without the source code being posted.
Things to check:
- If you are using SQL 2005, and more than one connection is opened, your transaction will be promoted to a MSDTC transaction.
- If you are using SQL 2008+, AND you have multiple connection open at the same time (i.e. nested connections or multiple ASYNC connections running in parallel), then the transaction will be promoted to a MSDTC transaction.
- If you have "try/catch{retry if timeout/deadlock}" logic that is running within your code, then this can cause issues when the transaction is within a
System.Transactions.TransactionScope
, because of the way that SQL Server automatically rolls back transaction when a timeout or deadlock occurs.