iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 7
2

Saga Pattern

之前介紹的Outbox Pattern可能需要透過排程或是MQ來做訊息交換.設計上會稍微複雜, 要引入MQ
Saga不必引入MQ, 因為是透過多次外部系統之間的通訊, 才能把整個事務從開始狀態轉成結束狀態.
但需要使用對策Countermeasure, 來防止或是減少由於缺少事務隔離而導致的併發異常.

1987年Hector & Kenneth發表Saga論文.
Saga也是微服務架構中維護資料一致性的機制.透過一來串的本地事務組成, 每一個本地事務負責更新它所在服務的私有資料庫. 所以這些本地事務還是依賴於ACID; 每一個本地事務的完成會觸發下一個本地事務的執行.
Saga有個別名叫做Long-lived transaction(長事務), 這裡的指的是跨越系統邊界的多次事務.核心概念是避免事務長時間持有對資源的鎖, 應該把長事務切分成一組按順序提交的短事務.

Transaction & Compensation Transaction

因為把長事務切成很多小的本地事務, 所以每個Saga會由一系列的sub-transaction Ti組成.
Saga依照正常事務(T1...Tn)依序執行.

本地ACID事務可以對資料進行Rollback,
但Saga沒辦法, 因為每個步驟都會把變更提交到本地資料庫,
依靠的是一種策略叫做"Compensation Transaction"的補償事務機制.
所以每個Ti都有對應的補償事務Ci.

如果第j個sub-transaction發生問題, 則開始對j之前的sub-transaction開始反向做補償
Saga依照正常事務(T1...Tj)的反向順序來依序執行補償事務(Cj...C1), 其中0 < j < n.

補償跟原來的Rollback不同, Rollback是真的可以恢復成原有的狀態, 但補償算是一種沖正的概念, 像是您在Line上發給女友一則訊息, 您也無法真的收回, 也只能用一則新的訊息"您已收回"的訊息, 指向原本的訊息ID, 然後做覆蓋, 原有的訊息狀態更改為"收回"; 因為您也無法跑到人家的裝置上刪除資訊XD
如果沒把資料庫做拆分, 滿足ACID的資料庫只要庫存不足或錯誤, 大家都在本機事務上, 其實訂單是不會成立的, 會直接Rollback.
但BASE下雖然最終訂單被Cancelled, 但其實訂單還是產生了QQ

上篇的例子Order與Inventory這次在加入User作為例子.

事務情境是, 建立訂單後檢查庫存, 若庫存正常替用戶扣款, 扣款成功則訂單完成.
我們把訂單, 商品, 用戶拆成三個獨立的服務並各自用私有的資料庫.
正常流程如下圖

  1. Order服務先建立訂單資料, 狀態設定成Opened, 完成本地事務後, 傳遞資訊給Inventory服務
  2. Inventory服務檢查庫存, 並鎖定庫存, 完成本地事務後, 傳遞資訊給Order服務
  3. Order服務變更訂單狀態成Prepared, 完成本地事務後, 傳遞資訊給Account服務
  4. Account服務進行扣款事務, 完成後, 傳遞資訊給Order服務
  5. Order服務變更訂單狀態成Commited

這樣的模式, 每一段小事務只需要鎖定本地資料庫的資料極短的時間.
但這種模式, 很難輕易Rollback, 只能透過補償(Compensation)機制來達到最終一致性(Eventually Consistent).

如上面的情境, 要是T2失敗, Order服務就要有接口可以對T1的事務做C1補償

要是T4的扣款失敗, 前面的T3,T2,T1都得做補償C3->C2->C1

當然補償事務理論上不會失敗, 但真實情況就是可能會失敗, 主機硬碟網路電力等等的問題.
慢慢來研究怎處理.

缺乏事務隔離

回到第一段Saga因為缺乏ACID的事務隔離特性, 所以其實Saga模式只滿足了ACD三個特性.
每個Saga的本地事務所作的更改, 會立刻被其他Saga給看到.
這樣會有幾個問題.

  1. 其他Saga就可以執行時, 更改該Saga所訪問的資料
  2. 其他Saga就可以在該Saga完成更新之前, 先讀取其資料, 導致資料不一致.

這就回到第三篇曾提到的Isolation 隔離性, 但沒講到的那幾個事務隔離級別要防範的Read現象.

  1. 丟失更新
  2. 髒讀
  3. 不可重複讀

明天再來慢慢往下講了


上一篇
微服務瞎談(6) BASE理論 & Transactional Outbox Pattern
下一篇
微服務瞎談(8) Saga, Choreography vs Orchestration
系列文
服務開發雜談33

尚未有邦友留言

立即登入留言