Telling when a transaction is done

The purpose of a transaction is to group a bunch of actions that an application takes together, and to either perform all of them or none of them as a unit.  It’s a pretty reasonable assumption, therefore, that a transaction should be sure that it includes all the actions an application intended before committing.  We certainly don’t want a partial transaction to commit.  Furthermore, in a distributed application, we don’t want any zombie transaction segments to hang around.

 

The simple case is, well, simple.  If I have a transaction that consists of a straight line of operations from a single thread of an application, the fact that the application said “commit” is probably enough. 

 

In other, slightly more complex cases, the application is embedded in an enterprise framework, such as COM+.  That framework will have rules that govern when an application segment that it is controlling is considered complete.  For instance, this is what is behind COM+’s DisableCommit, or Indigo’s AutoCompleteTransaction property.

 

Behind the scenes, logically what is happening in these systems is that the framework is enlisting in the transaction.  The resource the enlistment is governing is that application segment’s notion of completeness.  If the segment is complete, based on the framework’s rules for completeness, the enlistment will vote yes, otherwise it will veto.  Furthermore, the frameworks will also be careful to ensure that no failures during communication are reported back as errors, and not hidden.

 

Here is a case where the enterprise framework is doing quite a bit of work for the application in order to ensure correctness.   But, System.Transactions decomposes transactions out of the enterprise framework, so what should an application do when it’s just using System.Transactions?

 

There are two underlying tools available.  The first is TransactionScope.  This is a thread local mechanism to ensure that the caller states specifically that it is done with the transaction.  If that is used throughout the application, then many of the completeness issues become moot.

 

The second mechanism is DependentTransaction.  This is a form of Transaction that is created using the DependentClone method of an existing Transaction object.  A DependentTransaction is both a normal Transaction object – you can enlist on it, you can issue Rollback, you can get the Identifier – and it incorporates a completion safety feature.  The application must call Complete on this object when it is done using it.  This is used internally by Indigo and by TransactionScope to ensure their completion safety.  However, it can also be used directly by an application.

 

There are two forms of DependentTransaction, which I’ll go into in my next post.

 

Update: A comment pointed out that I probably meant SetComplete, rather than DisableCommit.  SetComplete is certainly applicable, and at first I just agreed.  However, I think both are applicable.  The goal for the transaction system is to have the application segments assert that they are ok with transaction commitment proceeding -- effectively from any instruction following the call used to make that assertion.  DisableCommit/EnableCommit/SetComplete all play with that assertion in varying ways.


Posted Mar 28 2005, 06:09 AM by jim-johnson

Comments

Nicholas Paldino [.NET/C# MVP] wrote re: Telling when a transaction is done
on 03-29-2005 6:20 AM
In the statement:

For instance, this is what is behind COM+’s DisableCommit, or Indigo’s AutoCompleteTransaction property.

I think you meant to use SetComplete instead of DisableCommit. DisableCommit allows the state of the object to be maintained in COM+ across calls, as well as have transactions distributed across calls.
Nicholas Paldino [.NET/C# MVP] wrote re: Telling when a transaction is done
on 03-30-2005 6:22 AM
I'd still have to disagree. You say:

That framework will have rules that govern when an application segment that it is controlling is considered complete.

And then you continue to say:

For instance, this is what is behind COM+’s DisableCommit, or Indigo’s AutoCompleteTransaction property.

The AutoCompleteTransaction property is basically a way for code to indicate to the current transaction context that it has completed everything in that transaction. I agree that this is analagous to SetComplete (or rather, it automatcially calls something like SetComplete).

However, calling DisableCommit does not imply that they are ok with transaction commitment proceeding. This is more apparent when you have other transaction contexts that are wired up within an existing transaction. If the parent transaction calls DisableCommit, it doesn't matter if all of the other contexts have SetComplete called on them, the transaction is put on hold until the context that had DisableCommit called on it has SetComplete called (or EnableCommit). From the documentation for DisableCommit:

Return Values

S_OK

The call to DisableCommit succeeded. The object's transactional updates can't be committed until the object calls either EnableCommit or SetComplete.
Jim Johnson wrote re: Telling when a transaction is done
on 03-30-2005 7:36 AM
Uhm, exactly. I wasn't suggesting that DisableCommit allowed transaction commitment to proceed. My point was that it was involved in the calculation as to whether or not the application had stated its doneness assertion.

If an application says DisableCommit, then th application has denied doneness. The transaction manager must not conclude that the application is willing for commitment to proceed.

That is analogous to not setting AutoCompleteTransaction on the Indigo operation, and also not calling the manual equivalent in that method.

In both cases, the assertion that the transaction system needs in order to successfully begin commitment has been denied. Hence both properties are relevant to the discussion.

Jim.

Add a Comment

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