首頁  >  文章  >  Java  >  跨多個服務的事務操作。一種瘋狂的方法。

跨多個服務的事務操作。一種瘋狂的方法。

Mary-Kate Olsen
Mary-Kate Olsen原創
2024-11-17 00:21:03703瀏覽

Transactional Operations Across Multiple Services. A Method To The Madness.

團隊在微服務環境中必須處理的眾多複雜問題之一就是事務。跨越多個微服務的事務。與單體應用程式不同,單體應用程式的事務通常使用單一資料庫和 @Transactional
進行管理 註解,在微服務中,每個服務往往都有自己的資料庫,使得分散式交易變得更加複雜。這是有關如何在 Spring Boot 中有效處理這些分散式交易的指南。

首先,讓我們先就什麼是交易達成一致。

事務是計算或資料庫環境中的一個工作單元,被視為單一不可分割的操作。它代表一系列必須一起成功或一起失敗的操作或步驟,即使在發生意外事件(例如斷電或網路故障)時也能確保資料的一致性和完整性

在資料庫上下文中,交易可能涉及多個查詢,例如建立、更新或刪除記錄。交易通常遵循四個基本屬性,稱為 ACID 屬性:

a. 原子性 - 事務中的所有操作都被視為一個單元。要嘛所有操作成功,要嘛全部失敗。

b. 一致性 - 交易將系統從一種有效狀態轉移到另一種有效狀態,從而保持資料有效性。

c. 隔離 - 交易是隔離執行的,這表示中間狀態對其他交易不可見。

d. 持久性 - 交易一旦提交,其更改就是永久性的,並且在系統崩潰時也能倖存。


一個短篇故事

在一個繁忙的電子商務應用程式中,想像客戶 Alice 訂購了一台新筆記型電腦、一個配件和快遞。以下是她的訂單如何在由 OrderSagaOrchestrator 管理的系統中流動的幕後故事。

在一個繁忙的電子商務應用程式中,想像客戶 Alice 訂購了一台新筆記型電腦、一個配件和快遞。以下是她的訂單如何在由 OrderSagaOrchestrator 管理的系統中流動的幕後故事。

Alice 輸入付款和送貨資訊後點擊「立即訂購」。此操作啟動了一個稱為傳奇的流程,這是一系列精心策劃的交易,以確保她的訂單從頭到尾得到正確處理。

第 1 步:付款處理
saga 編排器首先檢查 PaymentService,發起呼叫以從 Alice 的帳戶中扣除所需的金額。呼叫 paymentService.processPayment() 方法,授權 Alice 付款。

第2步:庫存預訂
一旦付款成功,協調器就會轉移到 InventoryService,為 Alice 保留特定的筆記型電腦型號和配件。此預訂步驟至關重要,以便在訂單仍在處理期間,庫存不會售罄或交給其他客戶。

第 3 步:出貨啟動
成功預訂庫存後,saga 協調器將聯繫 ShippingService。在這裡,shippingService.initiateShipping() 啟動物流,確保物品包裝好並準備好運送到 Alice 的地址。

處理失敗:補償邏輯

但是在分散式環境中,任何一步都可能出錯。如果因為物流錯誤而導致出貨失敗,或者由於庫存差異而實際上無法履行庫存怎麼辦?協調器已準備好補償策略。

如果拋出異常,協調器將啟動補償事務以回滾整個過程,因此 Alice 不會為她不會收到的物品付費:

3.1。取消出貨 - 協調器呼叫shippingService.cancelShipping(),停止出貨。

3.2。釋放庫存 - 然後觸發 inventoryService.releaseInventory(),釋放 Alice 的保留物品,以便其他客戶可以購買它們。

3.3。退款 - 最後,它調用 paymentService.refund() 來退還 Alice 的付款,確保她不會為訂單付費。

最後,這個精心策劃的傳奇確保了 Alice 的體驗流暢且一致,如果出現任何問題,都會以維護系統完整性的方式解決。這就是微服務中分散式事務和補償邏輯的魔力。


現在我們知道了什麼是事務並了解了事務可能有用的現實場景,讓我們深入研究如何在分散式環境中實現此功能。

團隊可以用一些關鍵方法來解決這個問題

1。 SAGA 模式: Saga 模式是微服務架構中處理分散式交易最廣泛使用的模式之一。傳奇是每個服務獨立執行的本地事務序列。 saga 中的每一步都會透過一個操作來補償,如果 saga 失敗,則該操作會撤銷該步驟。

Saga 模式可以透過兩種主要方式實現:

  1. a。 基於編排的 SAGA: 交易中涉及的每個服務都會偵聽事件並執行其事務。完成後,它會發出一個事件來觸發傳奇中的下一步。如果某個步驟失敗,則會觸發補償事件以撤銷先前的步驟。

  2. b。 基於編排的 SAGA: 集中式服務(saga 編排器)協調 saga 的步驟。它確定操作順序並管理發生故障時的補償。

2。兩階段提交(2PC): 雖然兩階段提交協定通常用於單體系統,但它可以透過 Atomikos 或 Bitronix 等分散式事務管理器跨分散式系統使用。但是,我不推薦這種方法,因為它在微服務上下文中存在一些限制,因為它會導致高延遲並且容錯能力較差。如果我是你,我通常會避免這種方法,而選擇 Saga 模式。

3。事件驅動架構: 使用事件驅動方法,服務透過事件進行通信,特別適合處理分散式事務。這種方法與 Saga 模式非常吻合。每個服務獨立執行其事務,然後發出事件以通知其他服務有關結果。這些事件可以使用 Apache Kafka、RabbitMQ 或其他訊息代理來處理。

現在,讓我們看看它在程式碼中是如何運作的。

saga 模式有多種風格,但在本文中,我將嘗試在 Spring Boot 中實現基於編排的 Saga 模式:

第 1 步: 定義 Saga Orchestrator:
在這裡,我將創建一個簡單的服務來充當協調器,負責協調事務。

該服務將定義傳奇的流程,以正確的順序呼叫每個服務,並在需要時處理補償事務。

第 2 步: 在每個服務中建立本地事務和補償方法:

每個服務都應該有自己的事務來完成其在傳奇中的步驟,並在需要時使用另一個事務來補償它。這是大概的結構。

第3 步: 基於事件的通訊(可選,用於編排):每個服務都可以發出事件來通知其他人交易的結果。

第 4 步: 採取措施確保資料一致性: 使用冪等性檢查來確保 saga 中的每個步驟僅執行一次。這在分散式系統中很重要,因為網路故障或重試可能會導致重複請求。

第5 步: 使用訊息代理來提高可靠性:如果您使用事件來管理傳奇,可以使用像RabbitMq 的Kafka 這樣的訊息代理持久性,並且可以在服務暫時不可用時緩衝事件。

第6 步: 錯誤處理和重試: 將錯誤處理和重試邏輯合併到您的協調器和各個服務中以處理臨時故障。 Spring Retry 在這裡很有用,因為它可以在可設定策略中自動重試失敗的操作。

結論

微服務中的分散式事務具有挑戰性,但透過使用 Saga(尤其是編排)和事件驅動通訊等模式,您可以實現可靠且可擴展的解決方案。

Spring Boot 透過提供對事務管理、事件發布以及與訊息代理整合的支持,使這一切變得更容易。

最後,這個精心策劃的傳奇確保了 Alice 的體驗流暢且一致,如果出現任何問題,都會以維護系統完整性的方式解決。這就是微服務中分散式事務和補償邏輯的魔力。

以上是跨多個服務的事務操作。一種瘋狂的方法。的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn