How to tell if a remote MSMQ queue is transactional?


[[Corrected December 17th, 2009, with input from Jolie Boushey]]


This isn’t going to be easy. There are two major obstacles to cope with



  • Private queues are, by definition, not published to Active Directory so their properties cannot be found with a simple query to directory services

  • As a result of that, the remote machine hosting the queue must be on-line to determine anything about the queue.

System.Messaging in .NET does include some useful looking options but unfortunately they fall short.



  • MessageQueue.Transactional property can only be checked on a local machine.

  • MessageQueue.GetPrivateQueuesByMachine method only returns a list of queue names without any other properties an array of MessageQueue objects that reference the retrieved private queues but not all properties are accessible for remote queues.

If you cannot check the properties then the next step is to use the queue and see what happens.


For example, this blog post shows how to determine if a queue exists:


http://blogs.msdn.com/johnbreakwell/archive/2008/07/31/checking-if-msmq-queues-exist-is-hard-work-so-should-you-bother.aspx


You could change it to send a transactional test message; if the message goes to the Transactional Dead Letter Queue with a class of “Nontransactional queue” then you know the queue isn’t transactional. Downside is what to do with the successfully delivered message if the queue IS transactional…


An alternative could be to do a transactional remote receive (assuming MSMQ 4.0 at both ends).
If you get 0xC00E0050 (MQ_ERROR_TRANSACTION_USAGE) then the queue isn’t transactional.
If you get receive a message because the queue was transactional then just abort the transaction to put it back in the queue.


If anyone has any more efficient methods to share then please post them here.

Comments (4)

  1. peter says:

    Hello,

    we have Windows Server 2003 and MSMQ 3.0. We want access a remote private queue over the internet. The Formatname is:

    "FormatName:DIRECT=TCP:XX.XX.XX.XXPrivate$test"

    We can connect over local networkt, but over remote we get a access user right error. We can write messages into queue, but can’t read it.

    can you help us?

    greets,

    peter

  2. MSDNArchive says:

    Hi Peter,

    Reading messages uses the RPC protocol. Normally this protocol is blocked on Internet-facing firewalls to prevent attacks through port 135.

    MSMQ 3.0 uses Secure RPC so – if the port is open and RPC traffic actually reaches the destination – I would check:

    http://blogs.msdn.com/johnbreakwell/archive/2007/01/15/msmq-3-0-too-secure-for-you.aspx

    Cheers

    John Breakwell (MSFT)

  3. jsternal says:

    Since GetPrivateQueuesByMachine returns an array of MessageQueue objects, can’t you iterate those, match your queue, and check MessageQueue.Transactional?

  4. MSDNArchive says:

    Hi JSternal,

    Thanks for suggesting that as it meant I had to review (and correct) my blog post.

    No, you shouldn’t be able to check MessageQueue.Transactional, regardless of how you create the queue object.

    Cheers

    John Breakwell (MSFT)