Another in the series of bitesize blog posts about features in MQ V8. Check out the whole series here.
MQ version 8 includes support for the latest version of the java message service (JMS) specification, which was released on the 21st of May 2013. There should be a separate bitesize blog on the contents of JMS 2 shortly, but I want to focus on one part: delivery delay.
Delivery delay allows an application to send a message and specify that the message will not be available for consumers to receive until a number of milliseconds have passed. For example an application might send a message into MQ with a delivery delay of 20 seconds. That message would be stored - more on this in a minute - by MQ until the 20 seconds had passed and then made available for receiving applications.
The following code snippet illustrates how delivery delay can be used using the new interfaces introduced in JMS 2. The MessageProducer interface has also been updated to support delivery delay.
JMSContext ctx = getContext();
Queue q = getQueue()
JMSProducer p = ctx.createProducer();
//Set delivery delay of 20 seconds, in milliseconds. This will apply to all messages sent from this producer until the value is changed.
p.setDeliveryDelay(20 * 1000);
p.send(q, "A delayed message");
Note that the delivery delay starts from the time that the message is received by the queue manager. This applies even if the message is sent in a transacted environment.
MQ implements delivery delay using a staging queue. This queue is called SYSTEM.DDELAY.LOCAL.QUEUE. When a message is sent with a delivery delay the queue manager intercepts the message and places it on the staging queue with header information which describes the target queue and the specified delivery delay. The delivery delay starts counting down to zero at this point. A component of the queue manager called the delivery delay processor (DDP) monitors the messages on the staging queue. Once a message's delivery delay has got to zero the DDP will get the message off the staging queue and place it on the target queue, assuming it still exists. The message can then be got by a consuming application. This is illustrated in the following picture:
This Knowledge Center page describes delivery delay in detail: "JMS 2.0 delivery delay". Note that if you want to use delivery delay on z/OS you need to manually create the staging queue. Having done this make sure you secure it to prevent ANY applications sending messages to it.
Two final points. Delivery delay is only available on MQ using the MQ classes for JMS, it is not available with any of the other APIs. Lastly, if you are going to use delivery delay with MQ then it is better to only use it with relatively short delays of, at most, a few minutes. If you are putting messages with long delays, perhaps several hours, then you might be better storing those messages in a database and sending them at a later point.