Bug at MsmqTransport.Send()

Developer
Dec 22, 2011 at 5:43 AM

Within the MsmqTransport.Send(), we call q.Send(toSend, GetTransactionTypeForSend()); to send the message through the msmq queues. By default, the endpoint queue are created as transaction queues. I run into the problem where the endpoint was sending a message to a transaction queue but without adding  <msmq destinationQueueIsTransactional="true"/> to the config file, it reverted the default setting from true to false causing q.Send(toSend, GetTransactionTypeForSend()); to fail. The biggest problem with this code is that GetTransactionTypeForSend() uses a transaction check on the endpoint from which the message is being sent rather than from the destination endpoint/queue. The currently implementation looks like this 

 

 private MessageQueueTransactionType GetTransactionTypeForSend()
        {
            if (DestinationQueueIsTransactional)
            {
                if (Transaction.Current != null)
                    return MessageQueueTransactionType.Automatic;
                return MessageQueueTransactionType.Single;
            }
            return MessageQueueTransactionType.None;
        }

 

Where DestinationQueueIsTransactional is a property of the sending endpoint. I believe this should be change to

 private MessageQueueTransactionType GetTransactionTypeForSend(MessageQueue queueToSend)
        {
            if (queueToSend.Transactional)
            {
                if (Transaction.Current != null)
                    return MessageQueueTransactionType.Automatic;
                return MessageQueueTransactionType.Single;
            }
            return MessageQueueTransactionType.None;
        }

and the call q.Send(toSend, GetTransactionTypeForSend()); should be changed to q.Send(toSend, GetTransactionTypeForSend(q));

Let me know what you think. I can check in my changes.

Coordinator
Dec 23, 2011 at 4:27 PM

Thanks for your comments. However I think it is correct behavior to fail if you have this configured for transactional processing, but the queue is set to non-transactional (or vice versa), instead of silently changing it to the necessary mode.