Transactional logging outside of transactions

I’ve constructed a central logging system for a solution that involves routing and processing messages on multiple private queues (MSMQ) using WCF. Within a contract method of a WCF service, I do some logging.
Here’s some abbreviated code to illustrate:

[OperationBehavior(TransactionScopeRequired = true, 
                   TransactionAutoComplete = true)]
public void ReceiveMessage(MsmqMessage<MyMessageContainer> msg)
{
    try{
        Logger.Log(LogLevel.DEBUG, "Message Processing...");
        // process the message here
        Logger.Log(LogLevel.DEBUG, "Message Processed.");
    }
    catch(Exception exp) {
        Logger.LogError(exp);
        throw exp;
    }
}

The ReceiveMessage is fired whenever a new message gets placed onto the queue that my service is monitoring. None of this is earth shattering. So, the full chain of events is…

  • Transaction Start
    • Receive Message
    • Log the Message
    • Process the Message
    • Log Completion
  • Transaction End

The Problem
The Logger itself writes to a transactional queue, so when an exception is thrown, not only does the inbound message get put back onto the queue, the logger messages don’t get put onto their queue. It’s a bit of a Catch-22. I’m using transactional logging so that I can be sure that log messages are captured, but the logging transaction gets caught up in the ambient transaction, effectively hiding all error logs.

The Solution
To ensure that Logger messages get written no matter what happens in the outer transaction, I’ve done the following in the Logger.Log method (again, simplified):

public void Log(LogLevel level, string message)
{
    using (TransactionScope scope = 
           new TransactionScope(TransactionScopeOption.Suppress))
    {
        // write message to log queue
    }
}

By executing the logging code within a new TransactionScope with the TransactionScopeOption.Suppress, it executes outside of any existing ambient transaction. It all seems to be working nicely, so if you see an issue with this pattern, I’d love to see any other solutions people have cooked up.

-jt
comments
nothing yet
Be the first to comment on this post!

Leave a comment

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>