Transaction Timeout When Using the RollBack Attribute

0 comments suggest edit

I noticed a recent check-in has added a TimeOut property to the RollBack attribute in MbUnit. Woohoo!

A while ago I presented the source code for a RollBack attribute for NUnit based on Roy Osherove’s work in the area. Well I found a little problem with using the RollBack attribute that affects the one I presented along with the one that comes packaged with MbUnit.

I uncovered the problem while running a particularly long running unit test. Every time I ran the test, it failed at just about exactly 61 seconds into it (I know, a unit taking that long is kind of useless for TDD, but I’ll get that time down to something manageable. I promise!).

I reran the test multiple times and the line of code it failed on would be different, but MbUnit was showing me that it was failing at 61 seconds every time. To prove it, I removed the RollBack attribute and ran the test and it succeeded after around 90 seconds (yeah, I have some heavy perf work to do, but it is a BIG test).

The error message I got each time was Distributed transaction completed. Either enlist this session in a new transaction or the NULL transaction.

Not a helpful message because I wasn’t attempting to complete the transaction. But the timing of the matter made it obvious to me I was running into a timeout issue.

The RollBack attribute works by enlisting a COM+ 1.5 transaction, which allows you to use Enterprise Services without inheriting from ServicedComponent using a feature called Services Without Components or SWC for short (gotta love them TLAs). To work around the issue in MbUnit, I simply removed the RollBack attribute and added the code to start a COM+ transaction directly to the method. The one change I made was to set the TransactionTimeout property which takes an integer timeout value in seconds.

[Test]

public void MyTest()

{

    ServiceConfig config = new ServiceConfig();

    config.TransactionTimeout = 120;

    config.Transaction = TransactionOption.RequiresNew;

    ServiceDomain.Enter(config);

    try

    {

        //Run my test code…

    }

    finally

    {

        if(ContextUtil.IsInTransaction)

        {

            //Abort the transaction.

            ContextUtil.SetAbort();

        }

        ServiceDomain.Leave();

    }

}

At the same time, I revisited the RollBack attribute I put together for NUnit and added a TransactionTimeout property to the attribute. That way you can mark up a test like so…

[Test]

[RollBack(120)]

public void MyTest()

{

    //Run my test code…

}

You can download the new version of the attribute for NUnit here.

As for MbUnit, I’ll mention this to the maintainers and we’ll hopefully see a fix soon.

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

4 responses

  1. Avatar for JIRA: MbUnit
    JIRA: MbUnit October 19th, 2005

    I wrote this up here...



    I need a way to specify a larger timeout for the com+ transaction than the default...

    http://haacked.com/archive/... MbUnit 2.22.00

  2. Avatar for Jonathan de Halleux
    Jonathan de Halleux October 20th, 2005

    Phil,



    MbUnit is extendible, i.e. you could write your own Rollback attribute and use in your project *without* recompilation of MbUnit.



    Cheers,

    Peli

  3. Avatar for Haacked
    Haacked October 20th, 2005

    True. But I still want to see the main codebase get updated. I have a workaround for now. I'll probably add that at some point.

  4. Avatar for JIRA: MbUnit
    JIRA: MbUnit December 5th, 2006

    I wrote this up here... <br /><br />I need a way to specify a larger timeout for the com+ transaction than the default...<br />http://haacked.com/archive/... MbUnit 2.22.00