WCF with Msmq

Poison and Retry message handling with MSMQ using WCF Net.Msmq binding

Transactional Queues Overview

In my earlier blog Setup MSMQ with WCF using Net.Msmq binding, we have learnt to setup non-transactional queues and process the queue messages with WCF Net.Msmq binding. Non-transactional queues are volatile queues and if (god forbid!) the queue manager crashes, all your messages are gone. Now, i am sure you would not want to risk and enterprise application with this.

To solve this purpose, we need to create Transactional queues, the process of creating queues remains the same as discussed in my previous article. The only change is select the checkbox for transactional queueTransactional Queue

Configure WCF to work with Transactional Queues

In order to work with Transactional queues, you need to enable WCF to work with transactions. First, specify the service behavior to specify the transaction Isolation Level (here i am using ReadUncommited for simplicity) and also the Operation behavior should have TransactionScopeRequired = trueWCFTransactions

Poison & Retry queue implementation

Since we are now dealing with transactional queues, we would want a failed/error message to be re-processed after sometime. For this, a retry queue is created. Please not retry queue is a sub-queue and not a separate queue. This is created implicitly once we configure the web config (as described further). Have a look at the web config binding attributes.

WebCOnfigBinding

Messages sent with ExactlyOnce set to true must be sent to a transactional queue only.

ExactlyOnce, when set to true, indicates that Message Queuing (MSMQ) ensures that a sent message is delivered to the receiving message queue once and only once.

ReceiveRetryCount. An integer value that indicates the maximum number of times to retry delivery of a message from the application queue to the application.

MaxRetryCycles. An integer value that indicates the maximum number of retry cycles. A retry cycle consists of transferring a message from the application queue to the retry subqueue and, after a configurable delay, from the retry subqueue back into the application queue to reattempt delivery. The default value is 2. On Windows Vista, the message is tried a maximum of (ReceiveRetryCount +1) * (MaxRetryCycles + 1) times. MaxRetryCycles is ignored on Windows Server 2003 and Windows XP.

RetryCycleDelay. The time delay between retry cycles. The default value is 30 minutes. MaxRetryCycles and RetryCycleDelay together provide a mechanism to address the problem where a retry after a periodic delay fixes the problem. For example, this handles a locked row set in SQL Server pending transaction commit.

Now, if the message fails to get processed (due to database deadlock or any other system exception), the message will go into a retry queue and will be picked up again for processing after the RetryCycleDelay. Once the retry cycles are complete and the message is still not processed successfully, the message will go into a Poison queue, which is again a sub-queue just like retry queue. The message will stay in this queue & would need manual intervention to look into the root cause of the failure.

I am migrating to Blogger for all my new blogs. You may visit https://helpmedevelop.blogspot.in/ for more insights

 

Leave a comment