關於Saga模式的介紹,已經有一篇文章介紹的很清楚了,鏈接在這里:分布式事務:Saga模式。
關於TCC模式的介紹,也已經有一篇文章介紹的很清楚了,鏈接在這里:關於如何實現一個TCC分布式事務框架的一點思考。
1. 子事務動作
Saga的子事務包含兩個動作:T和C;TCC的子事務包含三個動作:Try、Commit、Cancel。Saga和TCC相比沒有“預留動作”。以經典的A轉賬給B的例子來說:
Saga:
- T1(A賬戶余額減少)
- C1(還原A賬戶余額)
- T2(B賬戶余額增加)
- C2(還原B賬戶余額)
TCC
- Try1(A賬戶余額預扣)
- Commit1(A賬戶余額減少)
- Cancel1(還原A賬戶余額)
- Try2(B賬戶余額預加)
- Commit2(B賬戶余額增加)
- Cancel2(還原B賬戶余額)
2. 子事務≠數據庫事務
這個需要從兩個層面進行展開:
- 首先,無論是Saga還是TCC,一個子事務都包含多個數據庫事務。上面的例子中:無論是Saga的T和C,還是TCC的Try、Commit和Cancel,都是一個個完整的數據庫事務,天然的具有數據庫自身的ACID特性。
- 其次,無論是Saga還是TCC,一個子事務可能並不是數據庫操作:比如調用文件服務器進行文件上傳、比如發送一封郵件。
3. ACID
這個也需要從兩個層面進行展開:
- 首先,從數據庫事務層面,在Saga和TCC的中間階段是不滿足一致性(業務邏輯的一致性,而非數據庫約束)的
- 其次,從整個分布式事務層面,在Saga和TCC的中間階段是不滿足隔離性的,其他事務可以看到當前事務執行的中間狀態
不過以上兩個問題都可以通過分布式鎖來解決,例如:在執行事務之前對A和B的賬戶進行加鎖,拒絕其他事務的讀寫操作,但是這樣會降低效率。強一致性和高可用性二選一
4. 冪等
關於冪等,要區分子事務是否滿足ACID。
- 子事務滿足ACID:例如子事務為數據庫事務,那么無論是TCC還是Saga,每一個動作都都可以順利完成或順利回滾,則不需要冪等性
- 子事務不滿足ACID:例如子事務為上傳文件, Saga和TCC的T可冪等可不冪等,如果T冪等則可以認為T必定成功則Saga的C和TCC的Cancel不再需要,如果Saga和TCC的T不冪等則Saga的C和TCC的Cancel必須能夠處理T部分完成的情況。Saga的C和TCC的Cancel必須冪等,否則當回滾執行失敗系統無法確定該再次嘗試回滾還是就此放棄。TCC的Commit不存在是否冪等問題,因為按照TCC的規則一旦Try成功則Commit必定成功。