如何从 WebSphere MQ 读取消息而不从队列中删除原始消息?
我有一个 Spring 应用程序,它从 WebSphere MQ 读取消息。 读完后,我有一个处理方法,它将处理从队列中检索的数据。
第 1 步:
response = jmsTemplate.receive();
//Message automatically removed from queue.
第 2 步:
process(response);
process方法有可能抛出异常。如果出现异常,我需要将消息保留在队列中。
这可能吗?他们有办法仅在用户确认后删除该消息吗?
我尝试添加以下内容:
jmsTemplate.setSessionAcknowledgeMode(javax.jms.Session.CLIENT_ACKNOWLEDGE);
...但该消息仍然被删除。
JmsTemplate
创建代码片段:
JndiConnectionFactorySupport connectionFactoryBean = new JndiConnectionFactorySupport();
connectionFactoryBean.setBindingsDir(this.bindingDir);
connectionFactoryBean
.setConnectionFactoryName(connectionFactoryName);
connectionFactoryBean.afterPropertiesSet();
jmsTemplate.setConnectionFactory(connectionFactoryBean.getObject());
JndiDestinationResolver destinationResolver = new JndiDestinationResolver();
destinationResolver.setJndiTemplate(connectionFactoryBean
.getJndiTemplate());
jmsTemplate.setDestinationResolver(destinationResolver);
jmsTemplate.setReceiveTimeout(20000);
jmsTemplate.setDefaultDestinationName(this.defaultDestinationName);
尝试了jmsTemplate.execute()
方法,如下所示:
@SuppressWarnings({ "unused", "unchecked" })
Message responseMessage = (Message) jmsTemplate.execute(
new SessionCallback() {
public Object doInJms(Session session)
throws JMSException {
MessageConsumer consumer = session
.createConsumer(jmsTemplate.getDestinationResolver().resolveDestinationName(session, "QUEUE_NAME", false));
Message response = consumer.receive(1);
try {
testMethod();//this method will throw exception.
response.acknowledge();
consumer.close();
} catch(Exception e){
consumer.close();//control will come here.
}
return response;
}
}, true);
最佳答案
您不能使用 receive()
方法执行此操作,因为当 receive 方法返回时操作已完成(从 session 角度来看)。
您需要运行 session 范围内可能失败的代码;例如使用 JmsTemplate.execute()
和 SessionCallback
- 像这样......
this.jmsTemplate.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
this.jmsTemplate.convertAndSend("foo", "bar");
try {
String value = this.jmsTemplate.execute(session -> {
MessageConsumer consumer = session.createConsumer(
this.jmsTemplate.getDestinationResolver().resolveDestinationName(session, "foo", false));
String result;
try {
Message received = consumer.receive(5000);
result = (String) this.jmsTemplate.getMessageConverter().fromMessage(received);
// Do some stuff that might throw an exception
received.acknowledge();
}
finally {
consumer.close();
}
return result;
}, true);
System.out.println(value);
}
catch (Exception e) {
e.printStackTrace();
}
关于java - 读取而不从 JMS 队列中删除消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42272904/