2015-02-11 63 views
2

我有一個JMSReceiver類正在MQ Queue上偵聽。該類實現MessageListener接口。我希望通過讓消息回滾來實現邏輯以重試指定次數的消息。爲此,我必須捕獲業務異常並將其包裝在RuntimeException中,以便將消息回滾到MQ並重播。我希望以更好的方式實現這一點。JMS 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(),但是當我這樣做時,重新傳遞計數不會增加,我可以重放消息。請建議更好的實現方法?

回答

1

您可以使用CLIENT_ACKNOWLEDGE創建JMS會話作爲消息確認模式。然後在onMessage()方法中,不要調用msg.Acknowledge()。不調用msg.Acknowledge()將確保相同的再次傳遞。

session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); 

請注意,對一條消息調用Acknowledge()將會確認自上次調用該方法以來接收到的所有消息。

更新

Session創建

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 
+0

我有那個代碼和拋出異常的代碼在確認之前。所以在例外的情況下,message.acknowledge永遠不會被調用。信息仍然沒有回滾。我不得不把這個運行時異常讓消息回滾 – 2015-02-11 14:21:02

+0

我想你需要檢查你的會話創建代碼。我更新了我使用的代碼片段。消息正在重新發送到我的應用程序 – Shashi 2015-02-11 15:01:57

+0

嗨Shashi,我檢查了我的代碼,並且我們正在使用多線程,所以如果其他線程確認消息所有消息befor ethe消息得到承認。拋出runtimeexception讓消息回滾的不良後果是什麼? – 2015-02-17 07:06:39