Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
One of my customers was trying to read a queue item within a DTC transactional context from a remote queue. He then aborted the transaction and expected to see the message back in the queue. However, that did not happen. He was trying to read from a Windows 7 machine. MSMQ was installed on a Windows Server 2008 R2 virtual machine. Both the machines were in the same domain.
He was using the code mentioned below :
using (var tran1 = new TransactionScope(TransactionScopeOption.Required))
{
using (var q1 = new MessageQueue(@"FormatName:Direct=OS:MachineName\private$\QueueName",true))
{
q1.Formatter = new BinaryMessageFormatter();
var newmsg1 = new MqProcessData(q1.Receive(MessageQueueTransactionType.Single).Body as string);
Assert.AreEqual(mqdata.EntityID, newmsg1.EntityID);
// Transaction.Current.Rollback();
q1.Close();
}
}
Using MessageQueueTransactionType.Single immediately commits after doing a remote read. So messages will not show up in the remote queue even if you try to abort the transaction.
So, here’s what I did.
I created test queue on a machine and posted 3 messages to that queue. From another machine, I ran the code mentioned below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Messaging;
using System.Transactions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
using (var scope = new TransactionScope())
using (var queue = new MessageQueue("formatname:Direct=OS:MachineName\\private$\\QueueName", true))
{
// timeout should be higher for remote queues
// transaction type should be None for non-transactional queues
var message = queue.Receive(TimeSpan.FromMilliseconds(0), MessageQueueTransactionType.Automatic);
// ...normal processing...
scope.Complete();
}
}
}
}
At the mentioned below line of the code, I placed a breakpoint and started executing the code.
var message = queue.Receive(TimeSpan.FromMilliseconds(0), MessageQueueTransactionType.Automatic);
When I reached the above line, the message was read from the queue.
I did not allow scope.Complete(); to be executed. I then stopped debugging (as good as aborting the transaction) and I could see message back in the remote queue.
Note: MSMQ 4.0 introduced transactional remote receive as a native feature. An application that wants to perform a transactional remote receive can simply perform the remote receive in the context of a local Distributed Transaction Coordinator (MS DTC) transaction.
Written by
Kshitij Dattani
Reviewed by
Jainath Ramanathan
Microsoft India GTSC
Comments
- Anonymous
November 01, 2013
What about the performance? I dont get more than 15 trans / sec on a remote client :-(