分佈式事務的產生的原因
- 數據庫分庫分表
- 由於單表的數據量巨大導致的分庫分表,則會涉及到多個數據庫的一致性問題。
- 應用SOA化
- 業務的服務化。多個業務中心有各自的數據庫,也會涉及多個數據庫的一致性問題
事務的ACID特性
分佈式事務本質也是一個事務,則需要滿足ACID特性。
- 原子性(A)
- 在整個事務中的所有操作,要麼全部完成,要麼全部不做,沒有中間狀態。
- 一致性(C)
- 事務必須始終保持系統處於一致的狀態,不管在任何給定的時間併發事務有多少。
- 隔離性(I)
- 隔離性就是說,事務與事務之間不會互相影響,一個事務的中間狀態不會被其他事務感知。
- 持久性(D)
- 一旦事務完成了,那麼事務對數據所做的變更就完全保存在了數據庫中,即使發生停電,系統宕機也是如此。
常見的分佈式事務解決方案
兩階段提交--XA提交機制
XA提交機制
- XA中大致分爲兩部分:
- 事務管理器:作爲全局的調度者,負責各個本地資源的提交和回滾
- 本地資源管理器:往往由數據庫實現
- XA機制將提交過程兩個階段
- prepare
- commit
流程:
- 事務管理模塊在prepare服務A的DB事務、服務B的DB事務都成功後。
- 逐個commit這些DB事務。
DB在prepare返回OK後,如果沒有收到來自事務管理模塊的commit/rollback請求則會一直保留該分支事務的數據。
出現錯誤的情況:
- 若在prepare階段出現故障,則回滾prepare過的分支事務,從而達到全局事務回滾。
- 若在commit階段出現故障,後續仍然可以再次commit那些未成功commit的分支事務,最終達到全局事務提交。
優點缺點
- 優點:實現簡單易懂
- 缺點:性能不理想,高併發場景下表現不佳
消息事務+最終一致性
流程
藉助消息隊列,在處理業務邏輯的地方,發送消息,業務邏輯處理成功後,提交消息,確保消息是發送成功的。成功後的消息去通知下一步操作的B系統服務,直到全部執行完畢。
出現錯誤的情況:
- 通過消息隊列投遞來進行處理,如果成功,則結束,如果沒有成功,則重試,直到成功。
- 但是注意要做到冪等性控制,因爲在系統調用沒有達到期望的結果後會重試,不然就會出現重複的問題。
優點缺點
- 優點:實現和邏輯簡單易懂,性能大幅度提升。
- 缺點:犧牲了一定的一致性,效果是最終一致性的。
三階段提交--TCC(Try-Confirm-Cancel)機制
流程:
- 事務管理模塊是在服務A、服務B執行完畢後即刻提交其參與的DB事務。
-
- 如果全局事務決定提交,則逐個調用服務A和服務B的confirm邏輯
- 如果全局事務決定回滾,則逐個調用服務A和服務B的cancel邏輯。
出現錯誤的情況:
- 只需要根據全局事務當前狀態,將服務A、服務B相應的confirm/cancel邏輯重新調用即可。
- 但是,confirm/cancel邏輯可能會被多次調用,因此,需要保證其冪等性。
優點缺點
- 優點:完全控制粒度
- 缺點:不同的業務場景所寫的代碼都不一樣,複用性較差。
參考資料
- 分佈式最終一致方案梳理,Bright Moon ‘ s Blog,https://www.cnblogs.com/BrightMoon/p/5622618.html
- 深入理解分佈式事務,高併發下分佈式事務的解決方案,mine_song,https://blog.csdn.net/mine_song/article/details/64118963
- 分佈式服務的事務如何處理? - bytefox的回答 - 知乎,
https://www.zhihu.com/question/29483490/answer/237665712 - TCC https://blog.csdn.net/pseudonym_/article/details/88061286