簡體   English   中英

與JMS(ActiveMQ)一起使用事務

[英]Using transactions with JMS (ActiveMQ)

在我們的后端,有幾個服務通過JMS與Apache ActiveMQ發送和接收消息。 每個服務都有一個到ActiveMQ代理的會話。 我們現在想要執行以下操作(偽代碼):

服務s1:

Message m = createMessage("s2","Hello World")
sendMessage(m)
try {
   Message answer = commit()
   ...
} catch (TransactionFailedException e){
   ...
}

服務s2:

onMessageReceive:
try {
   Message m = getReceivedMessage()
   Message answer = doSomeStuff()
   send(answer)
} (Exception e) {
   rollback()
}

提交顯然必須阻止,直到答案到達或交易失敗。 服務s2也應該可能創建一個新的嵌套事務,因為s2正在向另一個服務發送消息。 如何使用ActiveMQ的事務來實現這種行為? 有一些示例可用,但在這些示例中,事務僅用作發送消息的批處理機制。

我正在解釋你的問題意味着你希望s2中的工作失敗導致s1中的正在進行的事務被回滾。

所以你要

s1 do some work

s2 do some work

if ( s2 OK )
   perhaps do even more work in s1
   commit s1
else
   rollback s1

JMS的異步模型不是為此目的而經典設計的。 根本原因是因為

  1. 在事務資源(例如數據庫記錄)被鎖定期間 - s1已完成一些工作,直到事務已解決,這些資源必須保持鎖定狀態。
  2. Asynch處理旨在將s2工作與s1工作分離,s2工作可能在請求放入隊列后幾分鍾或幾天內發生。 S2無法知道s1是否還在等他。 JMS的整個設計點是在s1和s2中解耦處理。

有兩種方法可以實現s1和s2之間的協調:

一種是使用真正的分布式事務,使用除JMS之外的協議,例如EJB可以將事務從一個進程傳播到另一個進程,或者使用WS-AtomicTransaction和Web服務。 這確實增加了操作復雜性 - 您必須管理事務日志和一個組件長期失敗的情況。

另一種方法是設計兩個協作系統,以穩健地處理“補償”工作。 你接受這一點,例如s2可能會失敗,並且有二次處理來處理重發請求,處理超時等。最后你可能會遇到人類需要參與的某些情況,但如果設計良好,這些情況可能是最小的。 在大型系統中,通常沒有替代方案,例如航空公司的預訂系統和連鎖酒店的預訂系統可能不適合分布式交易協調,因此除了經過一些精心處理以管理預訂航班和房間之外別無選擇。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM