views:

55

answers:

2

In order to select data from part of an application that isn't affected by dirty data, I create a TransactionScope that specifies a ReadUncommitted IsolationLevel as per the suggestion from Hanselman here.

My question is, do I still need to execute the oTS.Complete() call at the end of the using block even if this transaction scope was not built for the purpose of bridging object dependencies across 2 databases during an Insert, Update, or Delete?

Ex:

List<string> oStrings = null;
using (SomeDataContext oCtxt = new SomeDataContext (sConnStr))
using (TransactionScope oTS = new TransactionScope(TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = System.Transactions.IsolationLevel.ReadUncommitted }))
{
     oStrings = oCtxt.EStrings.ToList();
     oTS.Complete();
}
+3  A: 

If it hasn't changed any data, then it won't itself do anything - but yes: it should have a Complete(), because there might be an outer transaction-scope around this one. If yours rolls-back, you've doomed the whole outer transaction. By completing your transaction you allow the outer transaction to continue unhindered.

Note that Complete() in this scenario is "free" anyway; in fact SQL Server always optimises towards Complete(), with rollback (Dispose() without Complete()) being the expensive one.

Marc Gravell
+1  A: 

Yes. A transaction can only end in a completion or a rollback, so if you don't complete it, it will automatically rollback. That would be more expensive even if there is no actual changes to undo, and it might possibly affect other transactions.

Guffa