views:

1664

answers:

4

I am writing a Windows service that pulls messages from an MSMQ and posts them to a legacy system (Baan). If the post fails or the machine goes down during the post, I don't want to loose the message. I am therefore using MSMQ transactions. I abort on failure, and I commit on success.

When working against a local queue, this code works well. But in production I will want to separate the machine (or machines) running the service from the queue itself. When I test against a remote queue, an System.Messaging.MessageQueueException is thrown: "The transaction usage is invalid."

I have verified that the queue in question is transactional.

Here's the code that receives from the queue:

// Begin a transaction.
_currentTransaction = new MessageQueueTransaction();
_currentTransaction.Begin();

Message message = queue.Receive(wait ? _queueTimeout : TimeSpan.Zero, _currentTransaction);
_logger.Info("Received a message on queue {0}: {1}.", queue.Path, message.Label);
WORK_ITEM item = (WORK_ITEM)message.Body;
return item;

Answer

I have since switched to SQL Service Broker. It supports remote transactional receive, whereas MSMQ 3.0 does not. And, as an added bonus, it already uses the SQL Server instance that we cluster and back up.

+2  A: 

Using TransactionScope should work provided the MSDTC is running on both machines.

MessageQueue queue = new MessageQueue("myqueue");
using (TransactionScope tx = new TransactionScope()) {
    Message message = queue.Receive(MessageQueueTransactionType.Automatic);
    tx.Complete();
}
Maurice
It would appear that this solution requires Message Queuing 4.0 (Windows Server 2008). Is that correct?
Michael L Perry
That is CORRECT.
Cheeso
+3  A: 

I left a comment asking about the version of MSMQ that you're using, as I think this is the cause of your problem. Transactional Receive wasn't implemented in the earlier versions of MSMQ. If that is the case, then this blog post explains your options.

Mitch Wheat
To be clear, Transactional Receive (dequeue) requires MSMQ 4.0 or later, which is available on Windows Server 2008 or later.
Cheeso
A: 

I have since switched to SQL Service Broker. It supports remote transactional receive, whereas MSMQ 3.0 does not. And, as an added bonus, it already uses the SQL Server instance that we cluster and back up.

Michael L Perry
and that's why my answer is no longer the accepted answer?? Cheers, dude!
Mitch Wheat
A: 

In order to use Transaction scope you must before verify that MSDTC is intalled and remote client connection was activated.

Install MSDTC is not a problem but activate remote client connection must cause reboot of the server (on windows server 2003 this is the case).

maybe this post can help you : How to activate MSDTC and remote client connection

fred