When working with the .NET TransactionScope we want to use simple, lightweight, (local) transactions and avoid escalating to distributed transactions if possible. This is not a problem when using SQL Server 2008+ and not nesting connections but if you are using SQL Server 2005 or other database systems read on:

DTC Escalation Overview

Distributed transactions consume significant system resources, being managed by the MS distributed transaction coordinator (DTC), which coordinates all of the resource managers accessed in the transaction.

It is a common misconception that using TransactionScope always involves the DTC. The TransactionScope includes transaction manager components to handle lightweight transactions without talking to the DTC. You can verify this by running a test with the DTC Service disabled.

Promotable transactions allow a transactions to remain lightweight until more than one database (or other resource manager) is brought into the transaction. Only at this point the transaction is promoted to a distributed transaction.

This allows you to see when transactions are promoted. You can view the trace in the Visual Studio output window too.

Avoid DTC Escalation

If you are running into unwanted escalations and want to avoid them, you may have to manually control connection opening and closing – by using a global connection, or by writing a custom connection manager. For examples see:

Expert C# 2008 Business Objects, ConnectionManager, ContextManager“…The result is that you should reuse one open database connection across all your objects when using a TransactionScope object for transactional support. This means you must write code to open the connection object and then make it available to all objects that will be interacting with the databasewithin the transaction. That can unnecessarily complicate what should be simple data access code.The Csla.Data.ConnectionManager class is intended to simplify this process by managing and automatically reusing a single database connection object. The result is that all data access code that uses a database connection object has the following structure:

“If the connection isn’t already open, a connection object is created and opened. If the connection is already open it is reused. When the last nested using block completes, the connection object is automatically disposed of.“

No. Enlist=False would defy the usage of TransactionScope, because all SQL using this connection will no longer take part in the current transaction. When using TransactionScope we want all connections to enlist to the current transaction. But we only want this to involve the DTC when the transaction is spanning multiple databases or other resource types.