事物補償模式 Compensating Transaction Pattern

為了保證最終一致性, 在錯誤發(fā)生時, 沿著整個錯誤的傳遞路徑進行undo操作. 對于復(fù)雜的工作流來說, 盡可能保證相互依賴的流程上數(shù)據(jù)語義的最終一致性.

問題

在分布式環(huán)境中, 大量的數(shù)據(jù)在節(jié)點間不斷的傳輸和被修改. 為了保證整個系統(tǒng)的性能, 任何一個節(jié)點往往都是要求最終一致性, 而不是全局強一致性. 在最終一致性的模式下, 分布式環(huán)境中的每個點維護自己的狀態(tài)機, 從全局來看, 整個系統(tǒng)處于不一致的狀態(tài). 但所有的節(jié)點在執(zhí)行完規(guī)定操作后, 整個系統(tǒng)可以最終達到一致的狀態(tài)(沒有新數(shù)據(jù)進來的情況下)

這種設(shè)計帶來的問題就是當一個操作在某個環(huán)節(jié)出問題了, 希望對數(shù)據(jù)進行回滾, 但是這個操作很可能無法成功. 因為上游的服務(wù)可能已經(jīng)使用了錯誤的數(shù)據(jù), 而下游服務(wù)可能還沒有把錯誤數(shù)據(jù)寫入. 回滾過程就不是簡單的達到一個正確的一致性狀態(tài), 而是達到一個業(yè)務(wù)可以容忍的一致性狀態(tài)

因此我們需要根據(jù)業(yè)務(wù)執(zhí)行一定的補償策略, 盡可能的回滾受到影響的數(shù)據(jù), 及時終止錯誤數(shù)據(jù)的傳播, 并對已經(jīng)出錯無法恢復(fù)的業(yè)務(wù)執(zhí)行一定的補償操作, 如根據(jù)日志進行非常重的重算, 或者等待新的正確數(shù)據(jù)覆蓋舊數(shù)據(jù)等.

解決

這種設(shè)計模式是和業(yè)務(wù)緊耦合的, 一般來說, 是通過維護一個業(yè)務(wù)流.系統(tǒng)會對整個業(yè)務(wù)流進行狀態(tài)記錄, 當回滾時, 針對workflow的狀態(tài)機進行回滾. 由于狀態(tài)機是維護在各個節(jié)點上的, 所以回滾過程可以并發(fā)進行.

從這個描述, 我們知道, 能夠執(zhí)行這種操作的業(yè)務(wù)必須是能夠接受最終一致性,所有操作必須是冪等的

決策

  • 錯誤判斷 一個業(yè)務(wù)是否失敗了往往是難以判斷的, 一種情況是服務(wù)端的exception則可以判斷為立即失敗. 另外一種, 如一個預(yù)約系統(tǒng), 預(yù)約醫(yī)生后醫(yī)生因急事無法赴約, 這種業(yè)務(wù)端的失敗很難被捕捉到

  • 補償機制難以被確定 如何回滾狀態(tài)機, 回滾過程失敗如何挽救等等都難以進行邏輯編程

  • 非冪等操作 非冪等的操作無法回滾很容易理解, 如何把冪等操作轉(zhuǎn)化成冪等操作是一個非常大的挑戰(zhàn)

  • 操作序列的影響 在回滾時可能又改變了很多狀態(tài), 能夠單獨回撤一個狀態(tài), 還是一起回滾, 回撤時的順序是否有影響?

示例

image.png

我們假設(shè)有這樣的一個業(yè)務(wù)場景是某旅游服務(wù)提供商, 客戶依次進行如下操作

  1. 訂Flight 1航班, 從北京到上海
  2. 訂Flight 2航班, 從上海到杭州
  3. 訂Flight 3航班, 從杭州回北京
  4. 在上海H1酒店訂一個房間
  5. 在杭州H2酒店訂一個房間

這一系列操作在業(yè)務(wù)上是相互關(guān)聯(lián)的, 但每個操作本身對于數(shù)據(jù)庫來說是原子的. 由于業(yè)務(wù)的異步性和延時性, 很可能客戶的所有航班和杭州的H2旅館反饋正常使用, 但上海H1旅館因為種種原因在2小時后返回失敗信息, 或者更進一步的, 返回信息表示取消之前成功的操作.

一個服務(wù)非常好的公司, 會注意到這個操作鏈, 通知用戶, 并根據(jù)用戶的意愿對關(guān)聯(lián)環(huán)節(jié)進行"回滾". 這里的"回滾"往往是基于策略的補償式的. 如發(fā)現(xiàn)用戶的航班購買成功, 但旅館失敗,則補償更高級別的同區(qū)域旅館, 旅館成功但航班失敗則補償票價并自動取消旅館的訂房.

類似這樣的業(yè)務(wù)操作, 需要能夠理解用戶意圖, 并把多個原子操作合并成相互關(guān)聯(lián)的一個大操作來面對.

同時再業(yè)務(wù)層對回滾進行策略編程, 形成基于業(yè)務(wù)的回滾機制

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容