2011-12-06 146 views
3

如何確保消息確認僅刪除消息,直至在jms代理中調用確認的消息。 目前我有一個系統,它從一個jms隊列中消耗並部分處理它。一段時間後,一批這些消息被另一個線程持久化。我現在需要對消息進行確認。但問題是我不得不停止使用消息,否則確認之前收到的消息也會確認接收到的所有其他消息。Jms消息僅在消息得到確認之前確認

換句話說,假設我有一個隊列中有10條消息。我消耗了其中的7個,然後在第5條消息上承認。這又消除了消費者從隊列中接收到的所有7個消息。是否有一種方法僅確認並從隊列中移除消息直到第5消息。

編輯:我試過創建兩個會話,並從不同的會話消耗,但(與Apache的qpid atleast)這執行不一致。我的意思是不一致,有時候在測試過程中,一個消費者能夠接收消息,而另一個消費者根本無法接收消息,無論你等待多久。這對我來說是一種解決方案,但由於不一致,無法將其作爲解決方案。

+0

您還沒有指定您正在使用的郵件提供程序。但據我所知,許多消息提供商不允許隨機的消息確認。如果您確認收到一條消息,則直到此時收到的所有消息也會被確認並從隊列中移除 – Shashi

+0

我使用apache qpid,並且我沒有做隨機確認,而是對特定消息做出確認。如果之前的所有消息都被清除,那麼確定,但是如果接收到更多消息,它們也會被刪除。 – Raks

回答

4

我知道這篇文章已經過時了,但這個答案應該會讓那些稍後偶然發現的人受益。

如果您想要細緻地控制您要確認哪些郵件,individual確認方法應該會對您有所幫助。使用此確認模式,您可以在會話中查看單個消息。未被確認的消息將被重新發送。

這不是規範的一部分,但大多數隊列提供程序在規範之外支持它。

Oracle

更多的靈活性,消息隊列可以自定義JMS 客戶確認模式。在客戶端確認模式下,客戶端 通過調用消息對象的確認()方法明確確認消息消耗。

的 標準的行爲,這種方法是導致會話承認 已經由出席會議的所有消費者自上次 調用方法消耗的所有消息。 (也就是說,會議承認當前 消息,所有以前未確認的消息,不管是誰 消耗他們。)

除了通過JMS規定的標準的行爲,消息隊列 ,您可以使用客戶確認模式在 時間確認一條消息。

public interface com.sun.messaging.jms.Message { 
      void acknowledgeThisMessage() throws JMSException; 
      void acknowledgeUpThroughThisMessage() throws JMSException; 
} 

ActiveMQ

可以想見其它確認模式,這將是有用的也爲 例如:CONSUMER_ACKNOWLEDGE其中Message.acknowledge()將 僅確認消息中接收了關於特定的MessageConsumer , 或CONSUMER_CHECKPOINT_ACKNOWLEDGE其中Message.acknowledge()將 只確認收到的消息,直到幷包括消息 實例該方法被調用。

但是,如果不着手所有這些不同的可能性, 有可能考慮只添加INDIVIDUAL_ACKNOWLEDGE 模式?僅此一項,就可以讓多線程應用程序實現他們所需的任何行爲。

connection.createQueueSession(false, ActiveMQSession.INDIVIDUAL_ACKNOWLEDGE); 

我沒有用過QPID個人,但是documentation hints的事實,個人信息的ACK是可能的。

Examples 
    # acknowledge all received messages 
    session.acknowledge 

    # acknowledge a single message 
    session.acknowledge :message => message 

在處理批處理時,您可以確認每個接收和處理的消息。如果遇到異常情況,請不要回復消息。

1

確認消息將使隊列管理器刪除該消息以及該消息之前收到的所有其他消息。它不應該刪除應用程序尚未收到的消息。您可能想要檢查您的應用程序,瞭解您如何確認消息。

+0

問題是消費者收到的所有消息都被刪除,並且它不依賴於您正在查看的消息。我想實現一些只能刪除某條消息的東西,即使我之後可能會收到更多的消息。這是必需的,因爲我批量處理消息,並且每當批處理完成時,我都需要確認該批次。而這批處理很耗時,所以我想繼續並行接收消息 – Raks

+0

不,這是不可能的。當收到一條消息時,所有收到的消息都將被刪除。您可能需要查看替代方案。 – Shashi