views:

105

answers:

3

I must use a corporate class that re-uses or re-creates a transaction after every Commit() or Rollback(). This class is told to use (or not use) transactions via a Boolean ctor parameter.

I am thinking of wrapping this API to separate the transaction support (to rely explicitly on Transaction objects or the ambient TransactionScope). But this requires a transaction class that is re-usable. Is there any such class in .NET? Or how would I begin to develop my own?

+3  A: 

No, transactions are not reusable once committed or rolledback (and I believe attempting to access them once they've been committed or rolledback will throw an exception).

My advice would be to forget trying to create a wrapper for TransactionScope, as it doesn't really provide any value since the TransactionScope model is implicit to begin with (and it's its own wrapper). Just throw your using (TransactionScope ts = new TransactionScope()) statements around things that need to be transactioned. With TransactionScope, every database call has implied transaction support.

Robert C. Barth
The class must know if it is transacted at construction. The individual methods do not have any transaction knowledge.
Anthony Mastrean
A: 

Write a wrapper method like so

TransactionScope GetTransaction(bool useTransaction)
{
   if (useTransaction)
   {
      return new TransactionScope( /* ... */ );
   }
   return null;
}

Using-Blocks will happily work with null-References so you could then write your code like this (where "useTransaction" is the boolean parameter you give to your class):

using (var scope = GetTransaction(useTransaction))
{
   // Code here (if useTransaction == true will use the ambient Transaction,
   // otherwhise will not run inside a transaction).

   if (scope != null)
   {
      scope.Complete();
   }
}
Christian.K
Will calling `new TransactionScope()` screw up events I attach to the `Transaction.Current.TransactionCompleted` event handler?
Anthony Mastrean
A: 

Update: The Session type has a separate non-transacted "acknowledge"-based behavior. I can individually acknowledge messages that I have finished processing. This allows me to avoid a Session-lifetime-based Transaction.

Anthony Mastrean