Doug
Doug

Reputation: 21

How to discard messages from queue using Java/JMS?

We have an application that synchronously reads 4MB messages from an IBM Websphere queue (version 7.5) using JMS. Under certain circumstances, I want to discard messages from the queue without reading them. I am trying to figure out if there is a way to do this programatically without reading the entire 4MB message, which takes several seconds (there could be hundreds of messages that need to be discarded). In the absense of a discard() method (or similar), here is what I have tried:

BytesMessage msg = (BytesMessage)queueReceiver.receiveNoWait();
bytesRead = msg.readBytes(msgBytes, 1024); // just read 1024 bytes
queueReceiver.close();

The above code is no quicker than retrieving the entire 4MB message from the queue (by reading into a larger buffer). This leads me to believe that the receiveNoWait() call is downloading the entire message into an internal buffer before the readBytes() call is made. The only other information I can provide is that the queue is set to "auto acknowledge" when the session is started:

queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);

If I were to change this to CLIENT_ACKNOWLEDGE and acknowlege the message using msg.acknowledge(), would that have the desired effect? Or is there something I am missing?

Thanks for any help, Doug

Upvotes: 2

Views: 3357

Answers (3)

Roger
Roger

Reputation: 7456

As far as I know, JMS cannot read part of a message. You can only do that with C or Java (non-JMS).

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQC.MQGMO_NO_WAIT + MQC.MQGMO_FAIL_IF_QUIESCING;

MQMessage getMsg = new MQMessage();
try
{
   /* get the message with only 1 byte of message data */
   _inQ.get(getMsg, gmo, 1);
}
catch (MQException e)
{
   System.err.println(e.getLocalizedMessage() );
}

Upvotes: 0

Calanais
Calanais

Reputation: 1580

Given this some more thought and there is potentially one other way here; MQ has the concept of PCF messages - simply this is being able to send an administrative command as a message to a queue manager.

JMS can send these messages - so one open would be to send a CLEAR_QUEUE command when you know you don't want any more messages.

It's quite a broad approach - clearing the entire queue but it depends on what your criteria are for removing messages.

I can see the use case however for selectively removing messages - maybe worth raising a 'request for enhancement' RFE on the IBM developerWorks site?

Upvotes: 0

Shashi
Shashi

Reputation: 15273

There is no other way, a message must be consumed to take remove it from a queue.

Changing to CLIENT_ACKNOWLEDGE from AUTO_ACKNOWLEDGE will not make any difference as the acknowledge is way to tell the messaging provider to remove a message from queue. The AUTO_ACKNOWLEDGE option tells the JMS client to automatically send a confirmation to provider to remove a message whereas CLIENT_ACKNOWLEDGE is used by the application to explicitly tell the provider to remove message(s).

You could probably take a look at setting an expiry time on messages that you don't plan to consume. Messages with an expiry time set, will not be available for delivery after the expiry time is over. Read through JMSExpiration property of a message.

Upvotes: 1

Related Questions