MaxConcurrentListeners and Remote Transactional Reads from MSMQ - msmq

Could it be that MaxConcurrentListereners on a DistributedTxMessageListenerContainer isn't much of use? I have the impression that only one thread at a time can handle a message from the queue. Maybe it's logical since the message will only be removed from the queue once the transaction is successfull. Or am I wrong here?

Yes, only one thread can receive a particular message from a queue.
Multiple threads can be receiving messages from a queue at any one time, though.
When a message is transactionally received from a queue, it becomes invisible to all other threads until the transaction aborts of commits.
If it aborts then the message reappears in the queue (made visible again); if it commits then the message is physically deleted from the queue.
Cheers
John Breakwell

Related

MSMQ transactional or recoverable

I have a question about MSMQ. If I use a non-transactional queue and send message to it with recoverable parameter, message is stored on disc and in case of some problem secure. But if I want pull message from non-transactional queue, is there some mechanism to secure messages to stay in queue in case of some problem (server error, db off...)?
For some reasons I don't want to use transactional queue. Thanks a lot for response.
You could implement a peek-then-receive process to simulate a transaction.
Peek message to get content.
Use the content as you wish.
If step 2 completes then Receive message to effectively delete it.
If step 2 fails, execute cleanup code and goto step 1.

MSMQ poison message means what?

I'm pretty new to this queue service and I don't know what really means poisoned message.
I read that is a message you cant consume, but It means you can Peek() and see the details but not Receive() or what?
From my point of view, I would say a poisoned message is a message on top of the queue that because of its format or even corrupted format is not consumible because the business in charge of handle it can't do it and it maybe generates a exception that in a transactional scenario is catched and handled with a rollback, so the message stays on top forever.
What do you think? Am I totally wrong?
I've had to deal with poison MSMQ messages before, ugh! I'd say your definition is close.
A poison message is basically a message that is repeatedly read from a queue when the service reading the message cannot process the message because of an exception or some other issue and terminates the transaction under which the message is read. In such cases, the message remains in the queue is retried again upon next read from the queue. This can theoretically go on forever if there is a problem with the message.
For example, the message contained data that would violate a database constraint. I sometimes would create an error queue and have the service processing the messages throw the "poison" message into that if an exception occurred during processing. This would at least remove the message from the queue and give me an opportunity to view it later without effecting the main production queues.
Here is some advice and information on poison message handling.

Transactional Dead-letter queue is filling up

Our Transactional Dead-letter queue is filling up in MSMQ. I can't find documentation on particular.net that points to why this could be happening.
It looks like every single message that is being processed (successfully) is ending up at the that queue.
What is the reason items are sent to the Transactional Dead Letter queue?
If you open dead letter queue in Computer Management, each message has a reason why it ended up there. It's under "class" column. That should point you where to look. For example one of reasons could be "The time-to-be-received has elapsed.", if message wasn't received within time specified in its "TimeToBeReceived" property.

Using MQMoveMessage

I'm trying to add poison message handling in my message queuing implementation. I'm receiving a batch of messages from a transactional queue, lets say 100, and if any are deemed 'poisonness', I want to move them to a subqueue where they can be handled separately.
The problem I'm having is knowing how to use MQMoveMessage. If I use it using the same transaction as the receive, I get an MQ_ERROR_MESSAGE_LOCKED_UNDER_TRANSACTION result code. If I use it after the receive transaction, I [of course] get a MQ_ERROR_MESSAGE_NOT_FOUND result code.
I imagine this works if I peek the message, since that doesn't lock the message, or remove it from the queue. However, that doesn't help since I'm receiving, and using a transactional queue.
Any help with this would be appreciated.
If anyone has the same issue, it appears the pattern is as above. That is, a transaction should be aborted, the message moves performed, and the transaction re-read.

MSMQ Adding a delay on Messages

I have a Microsoft Message Queue that gets populated with messages. If there is a problem with the processing of the message, I would like to retry the message, I do not want to retry the message immidiatley.
Is there a way to add a delay to the message in the MSMQ to avoid it being available for a certain amount of time??
The other alternative is to have another queue (A retry queue) and read that queue every 15 minutes, But i would rather not do this.
What you are looking for is "Poison Message Handling" ( even if its not the message fault, but an temporary environment problem ).
There are lots of articles on that. Here are some:
Poison Message Handling in MSMQ 3.0
Poison Message Handling in MSMQ 4.0
Surviving poison messages in MSMQ
In short: you have to move them to a retry queue.
So I've seen some code recently that handles this in the exception logic, the code has a built in retry step that attempts after a delay. It fails, waits for a specific amount of time, then tries again.
Essentially it recursively tries a set number of times (lengthening the delay each time). Fairly neat, no reason to have another queue. There is alot of generics and delegates used to execute the methods. Don't know if something like this could be done or not. I would suspect you would still want to handle the case of the message not being able to be delivered with another queue though.