In my integration scenario I needed to implement request/response interface between application running on Mainframe (Supplier) platform and windows (Biztalk ) . The communication between the platforms done with WMQ.
General MQ Stuff
In WMQ you have great feature for Correlation. When putting a message to a queue with MQMD_MsgID set to Null, WMQ Server generates a unique ID for this message and thus you can correlate the transaction with this MQMD_MsgID. The supplier get the message from queue, do it's stuff, sets the Correlation_ID of the response message to the MQMD_MsgID of the received message and puts it to queue.
All the client need to do is to listen on the queue for a message with Correlation_ID equal to it request MSG_ID.
Biztalk implementation
Biztalk support this way of work with it's MQSeries/MQC adapters using the solicit response port type. When issue the put to queue command with the adapter, you get the MQMD_MsgID which was assigned to your message by the WMQ Manger. The adapter copies it's also to the MQSeries.BizTalk_CorrelationId, thus you can work only with it and not using the MQMD_MsgID/MQMD_CorrelationID (on receive).
To implement this you need to do the next steps, by best practices :
- Create solicit-response port for the destination wmq queue.
- Create Correlation Set based on MQSeries.BizTalk_CorrelationId. this context property will be initiate automatically by the adapter with the MQMD_MsgID created by the WMQ Manager after issue the send to queue port.
- Create "dummy send" port for dev null/ NOPE adapter for the Correlation Set initialization. (*)
- Setting the Correlation set on the receive shape, waiting for the responce. The adapter will set the MQSeries.BizTalk_CorrelationId with the value of the MQMD_CorrelationID.
(*) see my previous post on this subject.
The Problem
seems simple yes, but there is a huge problem in step 3 and 4 because they are not an atomic transaction.
What will happen if biztalk will get a response message prior the setting of the Correlation Set, you will get the no subscribers error, because the Orchestration did not succeeded yet to subscribe it self in the message engine for this particular message.
We got a Race Condition problem.
Yep I got it , the roundtrip of the message from Biztalk to Mainframe , suppliers work, and back took less time than the Correlation Set initialization in biztalk. Surprised I WAS too.
SolutionSo to solve it I needed to write my own code for unique message id generation and set the correlation set before sending the request message with it.
Summery
Be aware of biztalk publish/subscribe latency.
On my next post I will give some tips for it optimization by administration table configuration. In this scenario it didn't help.