補償交易模式

Azure

當您使用由一系列步驟組成的最終一致作業時,補償交易模式可能會很有用。 具體而言,如果一或多個步驟失敗,您可以使用補償交易模式來復原步驟執行的工作。 一般而言,您會在雲端裝載的應用程式中找到遵循最終一致性模型的作業,以實作複雜的商務程式和工作流程。

內容和問題

在雲端中執行的應用程式經常修改數據。 此數據有時會分散到不同地理位置的各種數據源。 為了避免競爭並改善分散式環境中的效能,應用程式不應該嘗試提供強式交易一致性。 相反地,應用程式應該實作最終一致性。 在最終的一致性模型中,一般商務作業是由一系列不同的步驟所組成。 當作業執行這些步驟時,系統狀態的整體檢視可能會不一致。 但是當作業完成且所有步驟都已執行時,系統應該會再次保持一致。

數據一致性入門提供分散式交易為何無法妥善調整的相關信息。 此資源也會列出最終一致性模型的準則。

最終一致性模型中的挑戰是如何處理失敗的步驟。 失敗之後,您可能需要復原作業中先前步驟完成的所有工作。 不過,您無法一律回復數據,因為應用程式的其他並行實例可能已變更數據。 即使在並行實例尚未變更數據的情況下,復原步驟可能比還原原始狀態更為複雜。 可能需要套用各種商務特定規則。 如需範例,請參閱本文稍後所述的旅遊網站

如果實作最終一致性的作業跨越數個異質數據存放區,復原作業中的步驟需要接著流覽每個數據存放區。 若要防止系統保持不一致,您必須可靠地復原您在每個資料存放區中執行的工作。

實作最終一致性之作業所影響的數據不一定會保留在資料庫中。 例如,請考慮服務導向架構 (SOA) 環境。 SOA 作業可以在服務中叫用動作,並導致該服務所持有的狀態變更。 若要復原作業,您也必須復原此狀態變更。 此程式可能涉及再次叫用服務,並執行另一個動作來反轉第一個動作的效果。

解決方案

解決方案是實作補償交易。 補償交易中的步驟會復原原始作業中步驟的效果。 直覺的方法,是將目前狀態取代為系統在作業開始時的狀態。 但是補償交易不一定會採用這種方法,因為它可能會覆寫應用程式其他並行實例所做的變更。 相反地,補償交易必須是將並行實例執行的任何工作納入考慮的智慧型手機進程。 此程式通常是應用程式特定的,由原始作業執行的工作本質所驅動。

常見的方法是使用工作流程來實作需要補償的最終一致作業。 當原始作業繼續進行時,系統會記錄每個步驟的相關信息,包括如何復原步驟執行的工作。 如果作業在任何時間點失敗,工作流程會透過已完成的步驟反轉。 在每個步驟中,工作流程都會執行反轉該步驟的工作。

兩個重要點是:

  • 補償交易可能不必以原始作業的確切反向順序復原工作。
  • 可能可以平行執行一些復原步驟。

這種方法類似於克萊門斯·瓦瑟斯部落格討論的傳奇策略。

補償交易是最終一致的作業本身,因此也可以失敗。 系統應該能夠在失敗時繼續補償交易,並繼續。 可能需要重複失敗的步驟,因此您應該將補償交易 中的步驟定義為等冪命令。 如需詳細資訊,請參閱 喬納森·奧利弗部落格上的等冪模式

在某些情況下,手動介入可能是從失敗步驟復原的唯一方法。 在這些情況下,系統應該引發警示,並盡可能提供有關失敗原因的資訊。

問題和考慮

當您決定如何實作此模式時,請考慮下列幾點:

  • 在實作最終一致性的作業中的步驟失敗時,可能不容易判斷。 步驟可能不會立即失敗。 相反地,它可能會遭到封鎖。 您可能需要實作逾時機制。

  • 一般化補償邏輯並不容易。 補償交易是應用程式特定的。 它依賴具有足夠資訊的應用程式,才能復原失敗作業中每個步驟的影響。

  • 您應該將補償交易中的步驟定義為等冪命令。 如果您這樣做,如果補償交易本身失敗,則可以重複這些步驟。

  • 處理步驟的基礎結構必須符合下列準則:

    • 它在原始作業和補償交易中具有復原性。
    • 它不會遺失補償失敗步驟所需的資訊。
    • 它會可靠地監視補償邏輯的進度。
  • 補償交易不一定會在原始作業開始時將系統數據傳回其狀態。 相反地,交易會補償作業在失敗之前成功完成的工作。

  • 補償交易中的步驟順序不一定與原始作業中的步驟完全相反。 例如,一個數據存放區可能比另一個數據存放區更敏感。 復原此存放區變更之補償交易中的步驟應該先發生。

  • 某些量值有助於增加整體活動成功的可能性。 具體而言,您可以針對完成作業所需的每個資源放置短期、逾時型鎖定。 您也可以事先取得這些資源。 然後,只有在取得所有資源之後,才執行工作。 在鎖定到期之前完成所有動作。

  • 比平常更寬容的重試邏輯有助於將觸發補償交易的失敗降到最低。 如果實作最終一致性的作業中的步驟失敗,請嘗試將失敗視為暫時性例外狀況並重複步驟。 只有在步驟重複失敗或無法復原時,才停止作業並起始補償交易。

  • 當您實作補償交易時,您會遇到許多在實作最終一致性時所面臨的相同挑戰。 如需詳細資訊,請參閱數據一致性入門中的一節。

使用此模式的時機

只有在失敗時必須復原的作業才使用此模式。 可能的話,請設計解決方案以避免需要補償交易的複雜性。

工作負載設計

架構設計人員應該評估可補償交易模式如何用於其工作負載的設計,以解決 Azure 良好架構架構支柱涵蓋的目標和原則。 例如:

要素 此模式如何支援支柱目標
可靠性設計決策可協助工作負載復原到故障,並確保它會在發生失敗后復原到完全正常運作的狀態。 補償動作會使用直接回復數據變更、中斷交易鎖定,或甚至執行原生系統行為來扭轉效果等程式,解決關鍵工作負載路徑中的故障。

- RE:02 重要流程
- RE:09 災害復原

如同任何設計決策,請考慮對其他可能以此模式導入之目標的任何取捨。

範例

客戶會使用旅遊網站來預訂行程。 單一行程可能包含一系列航班和酒店。 從西雅圖到倫敦,然後前往巴黎的客戶,可能會在建立行程時執行下列步驟:

  1. 預訂從西雅圖飛往倫敦的 F1 航班座位。
  2. 預訂從倫敦飛往巴黎的 F2 航班座位。
  3. 預訂從巴黎飛往西雅圖的 F3 航班座位。
  4. 預訂倫敦H1酒店的房間。
  5. 在巴黎 H2 酒店預訂房間。

這些步驟構成最終一致的作業,雖然每個步驟都是個別的動作。 除了執行這些步驟,系統也必須記錄計數器作業,以復原每個步驟。 如果客戶取消行程,則需要此資訊。 接著,執行計數器作業所需的步驟可以執行為補償交易。

補償交易中的步驟可能與原始步驟完全相反。 此外,補償交易中每個步驟中的邏輯都必須將商務特定規則納入考慮。 例如,取消航班預訂可能無法讓客戶獲得完整的退款。

下圖顯示預訂旅行行程的長時間執行交易中的步驟。 您也可以查看復原交易的補償交易步驟。

顯示建立路線步驟的圖表。也會顯示取消行程之補償交易的步驟。

注意

您可以根據設計每個步驟的補償邏輯,以平行方式執行補償交易中的步驟。

在許多商務解決方案中,單一步驟的失敗不一定需要使用補償交易來回復系統。 例如,請考慮旅遊網站案例。 假設客戶預訂航班 F1、F2 和 F3,但無法預訂 H1 酒店的房間。 最好在相同城市的不同酒店為客戶提供房間,而不是取消航班。 客戶仍然可以決定取消。 在此情況下,補償交易會執行並復原 F1、F2 和 F3 航班的預訂。 但客戶應該做出這個決定,而不是系統。

下一步

  • 數據一致性入門。 補償交易模式通常用於復原實作最終一致性模型的作業。 此入門提供最終一致性優點和取捨的相關信息。
  • 等冪模式。 在補償交易中,最好使用等冪命令。 此部落格文章說明實作等冪性時需要考慮的因素。
  • 排程器代理程式監督員模式。 本文說明如何實作復原系統,以執行使用分散式服務和資源的商務作業。 在這些系統中,您有時需要使用補償交易來復原作業執行的工作。
  • 重試模式。 補償交易在計算上可能要求高。 您可以使用重試模式來實作重試失敗作業的有效原則,以盡量減少其使用次數。
  • Saga 分散式交易模式。 本文說明如何使用Saga模式來管理分散式交易案例中微服務之間的數據一致性。 Saga 模式會使用補償交易來處理失敗復原。
  • 管道和篩選模式。 本文說明管道和篩選模式,可用來將複雜的處理工作分解成一系列可重複使用的元素。 您可以使用管道和篩選模式搭配補償交易模式,作為實作分散式交易的替代方案。
  • 自我修復的設計。 本指南說明如何設計自我修復應用程式。 您可以使用補償交易作為自我修復方法的一部分。