When you create a new TransactionScope, you might be surprised to find that the default isolation level is Serializable.
TransactionScope’s default constructor defaults the isolation level to Serializable and the timeout to 1 minute. In SQL Server, SERIALIZABLE transactions are rarely useful and prone to deadlocks.
If you are using a TransactionScope and getting deadlocks in your application (and hopefully you have a retry mechanism for SQLException 1205), it might be due to the Serializable isolation level.
Instead of using the default constructor:
using
(
var
scope =
new
TransactionScope())
{
// .... Do Stuff ....
scope.Complete();
}
Use this:
using
(
var
scope = TransactionUtils.CreateTransactionScope())
{
// .... Do Stuff ....
scope.Complete();
}
.....
public
class
TransactionUtils
{
public
static
TransactionScope CreateTransactionScope()
{
var
transactionOptions =
new
TransactionOptions
{
IsolationLevel = IsolationLevel.ReadCommitted,
Timeout = TransactionManager.MaximumTimeout
};
return
new
TransactionScope(TransactionScopeOption.Required, transactionOptions);
}
}
[The other gotcha relates to SQL Server 2014 and below: TransactionScope and Connection Pooling]