[英]Read without removing message from JMS queue
如何從 WebSphere MQ 讀取消息而不從隊列中刪除原始消息?
我有從 WebSphere MQ 讀取消息的 spring 應用程序。 閱讀后,我有一個 process 方法可以處理從隊列中檢索到的數據。
第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()
方法不能這樣做,因為當接收方法返回時操作已完成(從會話的角度來看)。
您需要運行可能在會話范圍內失敗的代碼; 例如,使用帶有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();
}
您可以添加 JMS 消息的事務處理。 看例子
你的聽眾應該被"transacted"
。 像這樣
<jms:listener-container connection-factory="connectionFactory" acknowledge="transacted">
<jms:listener ref="notificationProcessor" destination="incoming.queue"/>
</jms:listener-container>
您必須瀏覽隊列。
使用 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); }
說明:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.