[英]JMS and MDB with setRollbackOnly
我有一個java類,它消耗來自隊列的消息,向一些URL發送HTTP調用。 我已經在谷歌和stackoverflow上進行了一些搜索(如果我錯過任何提及該問題的消息來源,我真的很抱歉)但是找不到有關setRollbackOnly調用的詳細信息。
我的問題是......如果我回滾,從隊列中消耗的消息將阻塞隊列的其余部分並將循環直到它成功處理或者它將在當前隊列的末尾重新排隊?
我用於從隊列中消費並發送HTTP調用的代碼如下所示,整個應用程序在Glassfish服務器上運行:
public class RequestSenderBean implements MessageListener { @Resource private MessageDrivenContext mdbContext; public RequestSenderBean(){} public void onMessage(final Message message) { try { if(message instanceof ObjectMessage) { String responseOfCall=sendHttpPost(URL, PARAMS_FROM_MESSAGE); if(responseOfCall.startsWith("Success")) { //Everything is OK, do some stuff } else if(responseOfCall.startsWith("Failure")) { //Failure, do some other stuff } } catch(final Exception e) { e.printStackTrace(); mdbContext.setRollbackOnly(); } } }
這是基本的JMS /消息傳遞知識。
隊列實現“負載平衡”場景,其中消息命中隊列並被消除一個消費者處理。 增加消費者數量會增加該隊列處理的潛在吞吐量。 隊列中的每條消息都將由一個且僅一個消費者處理。
主題提供發布 - 訂閱語義:主題的所有使用者都將收到推送到主題的消息。
考慮到這一點,一旦消息被解除並且(以事務方式)傳遞給消費者,如果它是異步的(如MDB的情況),它決不會阻塞隊列的其余部分。
正如Java EE教程所述 :
消息消費
消息傳遞產品本質上是異步的:消息的生成和消費之間沒有基本的時序依賴性。 但是,JMS規范更精確地使用了這個術語。 消息可以通過以下兩種方式之一消費:
同步:訂閱者或接收者通過調用receive方法顯式地從目標獲取消息。 接收方法可以阻止,直到消息到達,或者如果消息未在指定的時間限制內到達,則可以超時。
異步:客戶端可以向消費者注冊消息監聽器。 消息偵聽器類似於事件偵聽器。 每當消息到達目的地時,JMS提供者通過調用偵聽器的onMessage方法來傳遞消息,該方法對消息的內容起作用。
因為您使用的MessageListener
根據定義是異步的 ,所以您不會阻塞隊列或其后續處理。
從教程中還有以下內容:
使用會話Bean生成和同步接收消息
生成消息或同步接收消息的應用程序可以使用會話bean來執行這些操作。 使用JMS API和會話Bean的應用程序中的示例使用無狀態會話Bean將消息發布到主題。
由於阻塞同步接收會占用服務器資源,因此在企業bean中使用此類接收調用並不是一種好的編程習慣。 相反,使用定時同步接收,或使用消息驅動的bean異步接收消息。 有關阻塞和定時同步接收的詳細信息,請參閱為同步接收示例編寫客戶端。
至於消息失敗,它取決於您的隊列配置方式。 您可以設置錯誤隊列(在Glassfish或Weblogic等容器的情況下),將失敗的消息推送到以后檢查。 在您的情況下,您正在使用setRollbackOnly
,因此處理 :
7.1.2編寫消息驅動Bean的編碼:MessageBean.java
消息驅動的bean類MessageBean.java實現了方法setMessageDrivenContext,ejbCreate,onMessage和ejbRemove。 onMessage方法幾乎與TextListener.java相同,將傳入消息強制轉換為TextMessage並顯示文本。 唯一重要的區別是它在異常的情況下調用MessageDrivenContext.setRollbackOnly方法。 此方法回滾事務,以便重新傳遞消息。
我建議您閱讀Java EE教程以及企業集成模式一書,其中詳細介紹了與產品/技術無關的消息傳遞概念。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.