Injecting Transactedness

As our team's primary goal is to promote ubiquity of transaction use, some of us have spent quite a bit of time thinking about the problems associated both with adding in new types of transacted resources, especially transacted variants of currently non-transacted resources, and in continuing to deal with a world where only part of your data is transaction aware, especially as it becomes the predominant part.

The answer that everyone would like to have is that we could wave a magic wand and suddenly non-transacted resources would just simply be transacted.  That I could just write:

atomic
{
    DoFirstThing ();
    DoSecondThing ();
}

And somehow everything done under DoFirstThing and DoSecondThing would be incorporated into the overall transaction -- even if DoFirstThing and DoSecondThing already exist and were written for a non-transacted world

For transaction-aware code written to System.Transactions, COM+, or Indigo, that is/will be effectively true.  But what about the objects and resources used in those, or other, routines that aren't transaction-aware?  Could we just make them transaction-aware?  This is what I call “injecting transactedness”.

It's a really seductive idea.  In the general case, though, it doesn't work.

The key is that by injecting transactedness the caller has changed the contract that the internal objects and resources have with DoFirstThing and DoSecondThing.

For instance, let's say that DoFirstThing does the following (in pseudo-code):

void DoFirstThing (string key, string val)
{
    hashTable.Add (key, val);
    try
    {
        using (TransactionScope s = new TransactionScope ())
        {
            ... get sql connection set up ...
            ... add {key, val} entry to sql table ...
            s.Complete ();
        }
    catch (Exception e)
    {
        if (!hashTable.ContainsKey (key))
            ... invariant check failed, terminate process ...
        hashTable.Remove (key);
    }
}

While this is a purposefully simplified pseudo-code example, here we have a case where if the transaction asynchronously aborts (and System.Transactions does do eager abort), this working code will suddenly fail an internal validity check and failfast.

There are other cases that are very easy to imagine, such as activity logs that are meant to record all activity, even that which eventually fails, or trace data.  There are more complex cases, as well:

  • many involve what happens at transaction abort, or
  • others involve multithreading and intended data leakage, or
  • others involve transaction-aware routines that always intended to be the roots of their transactions.

All are examples of what happens when you change the semantic contract of another software component from the outside.


Posted Apr 27 2005, 09:25 PM by jim-johnson

Comments

Sahil Malik wrote re: Injecting Transactedness
on 04-28-2005 4:55 AM
Hey Jim,

It'd be hella nice if you could show an example of IPromotableSinglePhaseNotification. There is just nothing out there as far as a simple code sample goes.

- SM
Patrick Foley wrote re: Injecting Transactedness
on 04-28-2005 5:01 AM
I am going to comment on something that I have not looked at yet. I apologize if something like this is already in 2.0 and I'm clueless.

Reading your post, the first thing that jumped into my mind for enlisting non-transacted resources in transactions is that in practice there are usually compensating operations. So if there is a DoFirstThing, then there very well could be UndoFirstThing.

Then if the transaction framework could fire an event like OnRollback, I'd at least be able to call UndoFirstThing manually.

This is obviously imperfect - it doesn't give me fully acid transactions - but it would seem to have great practical value for me, since non-transacted resources are a reality.

Is there something like this I should look at?
Jim Johnson wrote re: Injecting Transactedness
on 04-28-2005 9:01 PM
These are both good topics:

Sahil, that sounds like a great suggestion.

Patrick, I can think of two ways, either using the TransactionCompletedEvent or by building a small specialist volatile resource manager (in other words, implementing IEnlistmentNotification, which doesn't sound as scary :) ). I'd like to do a small post on these two, and the tradeoffs in between.

I have to confess to being pretty busy just now, so it may be a couple of days.

Jim.
Patrick Foley wrote re: Injecting Transactedness
on 04-29-2005 7:45 AM
So cool - thanks. No rush on my account.
Tecnologie .NET (Dotnet) wrote Transazioni in .NET 2.0
on 09-12-2005 3:55 PM

Add a Comment

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