Transactional Queue in .NET

In my previous article, we studied what is MSMQ (Microsoft Messaging Queue) and its implementation... But that's not the end of the story.

There are still some loopholes in the simple queue architecture, which we will be discussing in this article and attempt to resolve.

Case

In the previous article Introduction to MSMQ we had taken the billing scenario. So you would be thinking the application was working fine, the users were getting mail then where's the problem?

As we know simple queue transaction is "Fire and Forget", in other words, actions are happening asynchronously but there might be chances of getting mails delivered twice or messages may be lost. MSMQ stores messages/data in memory when they are sent or received across different machines. So if the machine holding the messages crashes then the messages are bound to get lost. But anyhow we can set the Recoverable property of the message to True. But this is not a proper solution.

Another problem could be Duplicate Messages.

To overcome this problem a Transactional Queue can be useful.

To implement transactional messaging, you would be required to create a transactional queue either from the computer management console or programmatically.

We will see both approaches one by one.

Computer Management Console

Step 1. Type compmgmt.msc in the Run window and press Enter.

Step 2. Right-click on "PrivateQueues" >> New >> Private Queue as in the following screenshot.

PrivateQueues

Step 3. After clicking on Private Queue, you will see the following screen.

Process order

Step 4. Now provide a good name for the queue; I used "ProcessOrder" and marked it as "Transactional". It makes your queue a "Transactional Queue".

So these were the steps to create a transactional queue from the Computer Management console. Now we will move to create it programmatically.

Step 1. Follow the same step that we did to create a non-transactional queue except using an extra parameter ("True").

MessageQueue billingQ = new MessageQueue();
billingQ.Path = @".\private$\processorder";

Screenshot

Non-transactional-queue

MessageQueue.Create(billingQ.Path, true);

As you can see in the screenshot, while specifying the path, you have to pass Boolean "true" to make it transactional.

Step 2. Sending a transactional queue message is somewhat different from a non-transactional queue.

Let's see how to send.

Step 3. Create a MessageQueueTransaction instance as below.

MessageQueueTransaction transQ = new MessageQueueTransaction();

Screenshot

Transactional-queue

In the screenshot you can see, that the first parameter is the object, the second parameter is the message label and the third parameter is the Transactional Queue instance we declared above.

Now the following screenshot shows how we can send two messages to different queues under a single transaction.

Advantage

If any of the queues fails, no transaction will occur, which is very useful whereas it's not possible in a non-transactional queue.

So in this way, we can create a transactional queue and send messages.

I have also attached the source code where you can clearly understand the transactional queue importance.

In the next article, we will explore more on the transactional queue. Thanks for reading.