Use the .NET TransactionScope

The TransactionScope class provides an elegant way to enclose a set of operations against resource managers in a transaction. Resource managers are:

  • Databases (SQL Server, Oracle, DB2, …)
  • MSMQ
  • Transactional NTFS file system TxF
  • Transactional Registry
  • Custom resource managers

See Introducing System.Transactions in the .NET Framework 2.0.

Beware! The default isolation level of TransactionScope is Serializable, while the default in Oracle and SQL Server tools and via ADO.NET or EF is Read Committed.

When working with the TransactionScope we want use lightweight transactions if they are sufficient. Beware of unwanted escalation to distributed (DTC) transactions.

Some warnings against using TransactionScope may come form using it with SQL Server’s default pessimist concurrency mode (not using row-versioning) where readers block writers and writers block readers, probably even with Serializable) and thus blocking the application to death.

What I like most about the TransactionScope is that it allows us to scope a transaction around a set of operation (~ unit of work ) in high (business) layers of an application, without using anything database specific (like SQLConnection, SQLTransaction) or  to passing transaction objects around through the layers.

Using tra = TransactionScopeFactory.CreateTransactionScope(TransactionScopeOption.RequiresNew,
                                                           IsolationLevel.Snapshot)
 SaveOrder 'to database
 EnqueueOrder 'via MSMQ
 tra.Complete()
End Using

BUG:  The Oracle Data Provider seems not to pick up the IsolationLevel    specified with TransactionScope. It seems to always use ReadCommitted.

Specifying a transaction isolation level uses a lengthy syntax:

Using tra As New TransactionScope(TransactionScopeOption.RequiresNew,
New TransactionOptions With {
.IsolationLevel = IsolationLevel.Snapshot,
.Timeout = TransactionManager.DefaultTimeout

}),
...
tra.Complete
End Using

Thus I use a TransactionScopeFactory:

Class TransactionScopeFactory
 'Using .DefaultTimeout to enable configuration, omitting .Timeout does not work
  Shared Function CreateTransactionScope() As TransactionScope
    Return CreateTransactionScope(TransactionScopeOption.Required, IsolationLevel.ReadCommitted)
  End Function
  Shared Function CreateTransactionScope(ByVal transactionScopeOption As TransactionScopeOption, ByVal isolationLevel As IsolationLevel) As TransactionScope
    Return New TransactionScope(transactionScopeOption,
                      New TransactionOptions With {
                          .IsolationLevel = isolationLevel,
                          .Timeout = TransactionManager.DefaultTimeout
                          })
  End Function
End Class

The default method CreateTransactionScop() makes it easy to play with different isolation levels when testing.

About Peter Meinl

IT Consultant
This entry was posted in Computers and Internet and tagged , , , , , , . Bookmark the permalink.

4 Responses to Use the .NET TransactionScope

  1. espinete says:

    hi mister, great !! any complete full source code sample about it ? thx

  2. Pingback: DB Concurrency Control with .NET – Overview « DuongTienLam's Blog

  3. Pingback: DB Concurrency Control with .NET – Overview – Know your Database System « DuongTienLam's Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s