我的應用程序在Tomcat下運行,其中一些Spring的DefaultMessageListenerContainer
正在監聽Oracle 11g Weblogic服務器下運行的多個不同的JMS隊列。JMS TextMessage,JMS_BEA_SELECT消息選擇器,事務會話和確認模式
DefaultMessageListenerContainer
配置是.. well ..默認爲sessionTransacted = false
和sessionAcknowledgeMode = AUTO_ACKNOWLEDGE
。我的應用程序收到的消息類型是javax.jms.TextMessage
。消息的實際正文(message.getText()
)是一個XML字符串。
當許多應用程序實例(開發框,測試框等)需要指向同一個JMS服務器時,我遇到了一個問題,因此一旦消息進入隊列,就不知道哪個服務器會使用它(我相信首先運行方法的那個)。問題是任何給定的應用程序實例只對專用於該特定應用程序實例的消息感興趣,因此對於當前配置,大多數消息都會丟失(由其他應用程序實例使用並在消息處理業務邏輯中被忽略)。
我對JMS服務器上執行沒有控制,但我可以迫使它在郵件正文中的特定XML元素設置爲一個應用程序實例特定值,這樣我就可以讀它,並決定哪些應用程序實例應該使用它。
最自然的做法是在DefaultMessageListenerContainer
上設置messageSelector
屬性,因此決定在JMS服務器上哪個消費者應該收到什麼消息。我還了解了Weblogic特定的JMS_BEA_SELECT
消息選擇器表達式,它適用於XML消息類型。不幸的是,它似乎沒有與XML有效載荷(或至少我不能使其工作)消息javax.jms.TextMessage
。我想,沒有運氣下面的表達式:
<property name="messageSelector" value="JMS_BEA_SELECT('xpath', '//Event/CorrelationID/text()') = 'MY_SELECTOR_TEST_3'"/>
根據this article其他選項有:
- 使用事務處理會話,然後回滾會話因此,該消息將返回到隊列中,可以被其他應用程序實例使用。
- 創建會話時使用Session.CLIENT_ACKNOWLEDGE,然後恢復會話,以便消息將返回到隊列並可供其他應用程序實例使用。
我明白,我需要設置sessionTransacted
和sessionAcknowledgeMode
上DefaultMessageListenerContainer
爲非默認值(什麼樣的價值觀?),然後回滾在消息處理代碼的會議(選項1)或不調用message.acknowledge()
(選項2)。
看起來像DefaultMessageListenerContainer
控制消息處理/會話生命週期。我如何定製它?
我最終設置了'sessionTransacted = true'(在javadoc中推薦),從'SessionAwareMessageListener'擴展我的消息處理器並進行'會話。當處理器將消息標識爲不適用於特定的應用程序實例時,rollback()'(我的問題中的選項1)。它似乎工作正常,但我真的很希望看到一個解決方案,它使用'messageSelector'和xpath將決策制定到JMS服務器中。 – parxier