Telling when a transaction is done -- DependentTransaction

In the last article I talked about the issue that, for safety, a transaction manager should know that an application has completed its actions before allowing a request to commt to successfully proceed.  This validation has been part of COM+, rather than MSDTC.  Given that System.Transactions decomposes the basic transaction mechanism out of the enterprise frameworks, such as COM+, what does it do to provide this safety feature?

The feature comes in the form of the DependentTransaction object.  This is obtained from a Transaction using the DependentClone method.  This takes a parameter to indicate the synchronization requirements to enforce the DependentTransaction, and is either RollbackIfNotComplete or BlockCommitUntilComplete.  In both cases, the application signals that it has completed by calling the Complete method on the DependentTransaction object.

RollbackIfNotComplete is the more traditional usage.  That is an assertion by the application that it expects to be complete with its activity prior to any request to commit.  Therefore, if commitment begins before the Complete method has been called there is a global application synchronization bug, and the transaction should abort.  If the application is using an RPC mechanism, or a messaging structure that has a return message, this is normally a pretty trivial assertion to make.

The code to obtain one would be:

DependentTransaction dtx = tx.DependentClone
                              (DependentCloneOption.BlockCommitUntilComplete);

This is then a Transaction object that can be used in the various ways that any other Transaction object can be used, with the addition that the application will need to issue a dtx.Complete () when it is done.

 

There is a second variation, BlockCommitUntilComplete, that deals with the cases where the synchronization would be less natural.  In many of those cases, the application today has synchronization logic only to ensure that the commit happens after all the processing has completed.  BlockCommitUntilComplete provides a mechanism to do that within System.Transactions, rather than through custom code in the application.

The simplest example of this is a transaction that makes use of a pool of worker threads.  The main thread would look something like:

using (TransactionScope scope = new TransactionScope ())
{
    for (int i = 0; i < 5; i++)
    {
        DependentTransaction dtx = Transaction.Current.DependentClone
                             (DependentCloneOptions.BlockCommitUntilComplete);
        ... queue a thread method Work (dtx, )
    }
    scope.Complete ();
}

Then, the routine Work would use the DependentTransaction object to set up its TransactionScope, and to declare that it is complete at the end.

In the meantime, the main thread will hang in the closing brace of the using statement until all five worker threads have completed.


Posted Apr 14 2005, 07:15 AM by jim-johnson

Comments

Nicholas Paldino [.NET/C# MVP] wrote re: Telling when a transaction is done -- DependentTransaction
on 04-14-2005 9:12 AM
Good post. I think that a natural follow-up to this post would show how transactions can be passed across thread boundaries (which is something that you don't see done often, especially in the COM+ space). Last I checked in Reflector, the classes in System.Transaction handled this quite nicely.
Jim Johnson wrote re: Telling when a transaction is done -- DependentTransaction
on 04-18-2005 6:02 AM
Thanks.

Yes, cross thread transactions would be a good example, and one that is pretty easy. I'll add an article with a more full example on this.

Jim.
Jim Johnson's Blog wrote Multithreading with DependentTransaction
on 05-01-2005 11:51 AM
Jim Johnson's Blog wrote How to pass a transaction along a chain of events
on 01-01-2006 1:53 PM

Add a Comment

(required)  
(optional)
(required)  
Remember Me?