我有一个正在侦听MQ队列的JMSReceiver类。此类实现MessageListener接口。我希望通过获取要回滚的消息来实现逻辑以重试指定次数的消息。为此,我必须捕获业务异常并将其包装在RuntimeException中,以便将消息回滚到MQ并进行重播。我希望以更好的方式实现这一点。
当前实施
class JMSReceiver implements MessageListener{
public void onMessage(Message msg){
logger.info("**********Message received in consumer");
try {
//Do some business which throws a business exception
} catch (Exception e) {
try {
logger.info("####Redelivery count"+msg.getIntProperty("JMSXDeliveryCount"));
if(msg.getIntProperty("JMSXDeliveryCount")<10){
logger.info("####MQ ISSUE: Redelivery attempted for message. Redelivery attempt: "+msg.getIntProperty("JMSXDeliveryCount"));
throw new RuntimeException("Redelivery Attempted"+e.getMessage());
}else{
logger.info("####MQ ISSUE: Redelivery attempts exhausted for message");
}
} catch (JMSException e1) {
e1.printStackTrace();
logger.info("####MQ ISSUE: Exception occured while getting JMSXDeliveryCount");
}
}
}
预期 以上实现有效。它将消息回滚到MQ并且重新传递计数增加。我甚至尝试过session.rollback(),但是当我这样做时,重新传递计数不会增加,我可以重播该消息。请告知更好的方法来实现这个目标?
答案 0 :(得分:2)
您可以使用CLIENT_ACKNOWLEDGE创建JMS会话作为消息确认模式。然后在onMessage()方法中,不要调用msg.Acknowledge()。不调用msg.Acknowledge()将确保再次传递相同内容。
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
请注意,在一条消息上调用Acknowledge()将确认自上次调用该方法以来收到的所有消息。
<强>更新强>
会话创建
connection = cf.createConnection("user","password");
System.out.println("Connection created.");
session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE);
System.out.println("Session created.");
OnMessage()方法 - 在第6次尝试时确认消息。
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message msg) {
try {
// Display the message that just arrived
System.out.println(msg);
if(msg.getIntProperty("JMSXDeliveryCount") > 5){
msg.acknowledge();
}
} // end try
catch (Exception e) {
System.out.println("Exception caught in onMessage():\n" + e);
}
return;
} // end onMessage()
}); // end setMessageListener