Chris Wignall
Chris Wignall

Reputation: 145

How to make BizTalk only take one message at a time from the MSMQ

I have a BizTalk orchestration that is picking up messages from an MSMQ. It processes the message and sends it on to another system.

The thing is, whenever a message is put on the queue, BizTalk dequeues it immediately even if it is still processing the previous message. This is a real pain because if I restart the orchestration then all the unprocessed messages get deleted.

Is there any way to make BizTalk only take one message at a time, so that it completely finishes processing the message before taking the next one?

Sorry if this is an obvious question, I have inherited a BizTalk system and can't find the answer online.

Upvotes: 2

Views: 718

Answers (2)

DTRT
DTRT

Reputation: 11050

While you can process the messages in order by using Ordered Delivery, there is no way to serialize to they way you're asking.

However, merely stopping the Orchestration should not delete anything, much less 'all the unprocessed messages'. Seems that's you problem.

You should be able to stop processing without losing anything.

If the Orchestration is going into a Suspended state, then all you need to do is Resume that one orchestration and any messages queued will remain and be processed. This would be the default behavior even if the app was created 'correctly' by accident ;).

When you Stop the Application, you're actually Terminating the existing Orchestration and everything associated with it, including any queued messages.

Here's your potential problem, if the original developer didn't properly handle the Port error, the Orchestration might get stuck in an un-finishable Loop. That would require a (very minor) mod to the Orchestration itself.

Upvotes: 0

tom redfern
tom redfern

Reputation: 31800

There are three properties of the BizTalk MSMQ adapter you could try to play around with:

batchSize

Specifies the number of messages that the adapter will take off the queue at a time. The default value is 20.

This may or may not help you. Even when set to 1, I suspect BTS will try to consume remaining "single" messages concurrently as it will always try parallel processing, but I may be wrong about that.

serialProcessing

Specifies messages are dequeued in the order they were enqueued. The default is false.

This is more likely to help because to guarantee ordered processing, you are fundamentally limited to single threaded processing. However, I'm not sure if this will be enough on its own, or whether it will only mediate the ordering of message delivery to the message box database. You may need to enable ordered delivery throughout the BTS application too, which can only be done at design time (i.e. require code changes).

transactional

Specifies that messages will be sent to the message box database as part of a DTC transaction. The default is false.

This will likely help with your other problem where messages are "getting lost". If the queue is non-transactional, and moreover, not enlisted in a larger transaction scope which reaches down to the message box DB, that will result in message loss if messages are dequeued but not processed. By making the whole process atomic, any messages which are not committed to the message box will be rolled back onto the queue.

Sources: https://msdn.microsoft.com/en-us/library/aa578644.aspx

Upvotes: 1

Related Questions