[英]Read without removing message from JMS queue
How to read a message from WebSphere MQ without deleting the original message from queue?如何从 WebSphere MQ 读取消息而不从队列中删除原始消息?
I have spring application which reads the message from the WebSphere MQ.我有从 WebSphere MQ 读取消息的 spring 应用程序。 After reading, I have a process method which will process the data retrieved from queue.
阅读后,我有一个 process 方法可以处理从队列中检索到的数据。
Step 1:第1步:
response = jmsTemplate.receive();
//Message automatically removed from queue.
Step 2:第2步:
process(response);
There are chances of throwing exceptions in process method.有可能在 process 方法中抛出异常。 In case of exceptions, I need to retain the message in the queue.
如果出现异常,我需要将消息保留在队列中。
Is it possible?是否可以? Is their any way to delete the message only on user acknowledgement?
他们有什么方法可以仅在用户确认后删除消息?
I tried adding the following:我尝试添加以下内容:
jmsTemplate.setSessionAcknowledgeMode(javax.jms.Session.CLIENT_ACKNOWLEDGE);
...but still the message is getting deleted. ...但消息仍然被删除。
JmsTemplate
creating code snippet: 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);
Tried the jmsTemplate.execute()
method as below:尝试
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);
You can't do that with receive()
methods because the operation is complete (from the session perspective) when the receive method returns.使用
receive()
方法不能这样做,因为当接收方法返回时操作已完成(从会话的角度来看)。
You need to run the code that might fail within the scope of the session;您需要运行可能在会话范围内失败的代码; eg with a
JmsTemplate.execute()
with a SessionCallback
- something like this...例如,使用带有
SessionCallback
的JmsTemplate.execute()
- 类似这样的......
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();
}
You can add transactional processing of JMS messages.您可以添加 JMS 消息的事务处理。 See the example
看例子
Your listener should be "transacted"
.你的听众应该被
"transacted"
。 Like this像这样
<jms:listener-container connection-factory="connectionFactory" acknowledge="transacted">
<jms:listener ref="notificationProcessor" destination="incoming.queue"/>
</jms:listener-container>
You have to browse the queue.您必须浏览队列。
Example of real code that was executed making usage of Websphere MQ使用 Websphere MQ 执行的真实代码示例
public void browseMessagesAndJiraCreation(String jiraUserName, String jiraPassword) { int counterMessages = jmsTemplate.browse(destinationQueueName, new BrowserCallback<Integer>() { @Override public Integer doInJms(final Session session, final QueueBrowser queueBrowser) throws JMSException { Enumeration<TextMessage> enumeration = queueBrowser.getEnumeration(); int counterMessages = 0; while (enumeration.hasMoreElements()) { counterMessages += 1; TextMessage msg = enumeration.nextElement(); logger.info("Found : {}", msg.getText()); JiraId jiraId = jiraManager.createIssue(jiraUserName, jiraPassword); jiraManager.attachFileToJira(jiraId, msg.getText(), jiraUserName, jiraPassword); } return counterMessages; } }); logger.info("{}:messages were browsed and processed from queue:{}.", counterMessages, destinationQueueName); }
Explanations:说明:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.