5
votes

I have a simple process which reads from one queue, processes the messages, and outputs to another. I am trying to wrap this transfer within a TransactionScope, such that both the read from the input queue, and the write to the output queue occurs within the same transaction.

However, it would appear that MSDTC is being used to conduct this transaction, and as a result it is significantly slower than using a standard MessageQueueTransaction. Should this be happening? I was under the impression that TransactionScope would only elevate to an external transaction if the scope involved, for instance, a message queue read, and a database write, but not if just multiple message queues were involved.

Thanks.

EDIT: This is all on my laptop at the moment, so I am sure that no other machines are involved.

I also want to add that I'm confirming that an escalated transaction is taking place by checking in Windows' 'Component Services' snap-in (i.e. the Local DTC / Transaction List). I can see the transactions entering and leaving this screen, which I assume means that the transaction has been escalated. Am I wrong in assuming this?

EDIT 2: I'm getting the same behaviour when I am just writing to a single queue! i.e.

using (var ts = new TransactionScope())
{
    using (var q = new MessageQueue("..."))
    {
        /* write data */
    }

    ts.Complete();
}

I can see the DTC being used with the above, despite the queue being on the local machine.

3
Where are the queues in relation to the app? Same machine? Different machine?John Breakwell
Are you using a clustered server?Jens H
No, this is all local on my laptop at the moment. I've updated my question with some clarification.Barguast

3 Answers

3
votes

It seems TransactionScope only handles external transactions in respect to message queues. You have to use MessageQueueTransaction if you want it to be internal only. This works differently with SQL transactions where the transaction is only escalated if required, which is what confused me.

0
votes

Have a look this MSDN article: Transaction Management Escalation

This list typical escalation behavior, like (highlights are mine):

When you want to provide the transaction to another object in another application domain (including across process and machine boundaries) on the same computer, the System.Transactions infrastructure automatically escalates the transaction to be managed by the Microsoft Distributed Transaction Coordinator (MSDTC). The escalation also occurs if you enlist another durable resource manager. When escalated, the transaction remains managed in its elevated state until its completion.

As you can see, elevation can happen not only when you are doing things over the network, but even if you are doing things on the same machine. (For example I recently had troubles in a case where I was accessing a MS SQL database from Windows service on the same (clustered) server.)

Also this could happen if a WCF service is involved somewhere in the process.

0
votes

It seems TransactionScope only handles external transactions in respect to message queues.

This statement is not true. TransactionScope will handle local transactions in message queues, it is just that it uses the MSDTC to do so.