如何使用Java / JMS从队列中丢弃消息?

时间:2014-09-23 22:49:06

标签: java queue jms mq

我们有一个应用程序,它使用JMS从IBM Websphere队列(版本7.5)同步读取4MB消息。在某些情况下,我想在不读取消息的情况下丢弃队列中的消息。我试图找出是否有办法以编程方式执行此操作而不读取整个4MB消息,这需要几秒钟(可能有数百条消息需要丢弃)。在discard()方法(或类似方法)的缺席中,这是我尝试过的:

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

上述代码并不比从队列中检索整个4MB消息快(通过读入更大的缓冲区)。这让我相信在调用readBytes()之前,receiveNoWait()调用正在将整个消息下载到内部缓冲区。我可以提供的唯一其他信息是在会话启动时队列设置为“自动确认”:

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

如果我要将其更改为CLIENT_ACKNOWLEDGE并使用msg.acknowledge()确认消息,那会产生预期的效果吗?或者有什么我想念的东西?

感谢您的帮助, 道格

3 个答案:

答案 0 :(得分:1)

没有其他方法,必须使用消息将其从队列中删除。

从AUTO_ACKNOWLEDGE更改为CLIENT_ACKNOWLEDGE不会有任何区别,因为确认是告诉消息传递提供程序从队列中删除消息的方法。 AUTO_ACKNOWLEDGE选项告诉JMS客户端自动向提供者发送确认以删除消息,而应用程序使用CLIENT_ACKNOWLEDGE明确告知提供者删除消息。

您可以查看为您不打算使用的邮件设置到期时间。设置了到期时间的邮件将在到期时间结束后无法发送。读取消息的JMSExpiration属性。

答案 1 :(得分:0)

鉴于此更多的思考,这里可能有另一种方式; MQ具有PCF消息的概念 - 只需将行政命令作为消息发送给队列管理器即可。

JMS可以发送这些消息 - 因此当您知道不再需要消息时,打开一个CLEAR_QUEUE命令。

这是一个非常广泛的方法 - 清除整个队列,但这取决于您删除邮件的标准。

我可以看到用例有选择地删除邮件 - 也许值得提出一个增强请求' IBM developerWorks站点上的RFE?

答案 2 :(得分:0)

据我所知,JMS无法读取部分消息。您只能使用C或Java(非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() );
}