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

如何使用Java/JMS丢弃队列中的消息?,java,queue,jms,mq,Java,Queue,Jms,Mq,我们有一个应用程序,它使用JMS从IBM Websphere队列(7.5版)同步读取4MB消息。在某些情况下,我希望丢弃队列中的消息而不读取它们。我正在试图找出是否有一种方法可以通过编程实现这一点,而无需阅读整个4MB消息,这需要几秒钟(可能有数百条消息需要丢弃)。在没有discard()方法(或类似方法)的情况下,我尝试了以下方法: BytesMessage msg = (BytesMessage)queueReceiver.receiveNoWait(); bytesRead = msg.r

我们有一个应用程序,它使用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消息快(通过读取到更大的缓冲区)。这使我相信receiveNoWait()调用是在readBytes()调用之前将整个消息下载到内部缓冲区中。我能提供的唯一其他信息是,当会话启动时,队列被设置为“自动确认”:

queueSession = queueConnection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
如果我将此更改为CLIENT_ACKNOWLEDGE,并使用msg.ACKNOWLEDGE()确认消息,是否会达到预期效果?还是我遗漏了什么

谢谢你的帮助,
Doug

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

将“自动确认”更改为“客户端确认”不会有任何区别,因为确认是通知消息传递提供程序从队列中删除消息的一种方式。AUTO_ACKNOWLEDGE选项告诉JMS客户端自动向提供程序发送确认以删除消息,而客户端_ACKNOWLEDGE则被应用程序用来显式地告诉提供程序删除消息


您可能会考虑设置不打算使用的邮件的过期时间。设置了过期时间的邮件在过期时间结束后将无法送达。通读消息的JMSExPrivation属性。

对此,请仔细考虑,这里可能还有另一种方法;MQ具有PCF消息的概念——简单地说,这就是能够将管理命令作为消息发送给队列管理器

JMS可以发送这些消息,所以当您知道不需要更多消息时,可以发送CLEAR_QUEUE命令

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


但是,我可以看到选择性地删除消息的用例——也许值得在IBM developerWorks站点上提出“增强请求”RFE?

据我所知,JMS无法读取消息的一部分。您只能使用C或Java(非JMS)来实现这一点


在activemq中,您可以直接使用消息,但我不确定这是否意味着要阅读消息来完成这项工作。问得好。你在如何将消息从服务器拉到客户端的问题上说得非常正确。该邮件是否有某些内容,例如确定是否应删除该邮件的属性?或者是其他条件?数据库中的状态代码告诉应用程序它不再需要队列中的消息(由于其他一些故障条件)。我无法清除整个队列,因为有其他线程正在处理其他消息。我只是想在不下载特定消息的情况下清除它们,而这似乎不可能使用JMS。如果IPPROC和/或OPPROC不为零,PCF clear_QUEUE命令将不起作用。各位,感谢您的回复。我确实尝试过使用客户端确认模式,正如Shashi预测的那样,它没有任何效果。不幸的是,我无法清除整个队列。此时,我的选择是让消息过期或全部下载它们。不幸的是,让它们过期对我来说似乎不是一个好的选择。测试表明,当其他线程正在检索消息时(我们使用相关ID检索消息),我们孤立了许多4MB消息,队列管理器的性能就会降低。再次感谢大家的反馈。
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() );
}