Do selectively dequeued messages stay in FIFO order (MQ)?
Using JMS & WebSphere MQ, if I use a message selector to selectively dequeue, and there are several messages with the same selection criteria, am I guaranteed to dequeue the first message that matches?
e.g. given a queue with messages
{color: pink, name: alice}
{color: blue, name: bob}
{color: red, name: charlie}
{color: blue, name: doug}
if I dequeue with the selector color='blue'
, am I guaranteed to dequeue {color: blue, name: bob}
? Or is there a chance I could get {co开发者_如何学运维lor: blue, name: doug}
instead, even though it is further into the queue depth?
Please refer to the RESCANINT property of the different WMQ Connection Factory implementations. From the manual:
When a message consumer in the point-to-point domain uses a message selector to select which messages it wants to receive, the WebSphere MQ JMS client searches the WebSphere MQ queue for suitable messages in the sequence determined by the MsgDeliverySequence attribute of the queue. When the client finds a suitable message and delivers it to the consumer, the client resumes the search for the next suitable message from its current position in the queue. The client continues to search the queue in this way until it reaches the end of the queue, or until the interval of time in milliseconds, as determined by the value of this property, has expired. In each case, the client returns to the beginning of the queue to continue its search, and a new time interval commences.
The idea is that in a very busy queue with priority delivery, some messages of a higher priority may appear higher in the queue then the current position of the selector. Theoretically a higher priority message should be consumed first but the consumer won't see it unless it seeks from the head of the queue. The cursor is reset to the head of the queue either when it gets to the end or when RESCANINT is reached. The setting of RESCANINT allows for tuning of how responsive you want the selector to be in finding these higher priority messages.
RESCANINT isn't specific to FIFO delivery. The other case in which this can happen is if there are multiple threads with overlapping selection criteria. In this case one thread can hold a message under lock and then release it. Although the message may be eligible for the second thread, if that thread has already passed that position in the queue then it takes hitting the end of the queue or RESCANINT elapsing to restart the cursor to find the message.
Rescan interval is in milliseconds and defaults to 5000. Any positive integer value is accepted, although too low a value will cause thrashing as the cursor is continually reset before any messages can be consumed.
As a practical matter, you will receive the messages in order if the queue is FIFO and you have only one reader on the queue for which the messages are eligible, regardless of what RESCANINT is set to. If message order is to be strictly preserved, there are some additional considerations as described in Sequential retrieval of messages. These boil down to messages having only one path from producer to consumer when considering channels, syncpoints, etc.
See the chapter "The order in which messages are retrieved from a queue" and the following: "Getting a particular message".
Summing up: the only way to get a message ignoring FIFO order is to fetch a specific message by its message id or correlation id. A queue may also be configured to deliver in FIFO + priority order, but that's not an option you consider. Finally, message ordering complicates if messages are grouped, but again, it's not your case.
精彩评论