當仍是單體應用,單體數據庫時,徹底不須要考慮事務的一致性問題,由於mysql已經幫咱們處理事務問題(ACID),可是這只是針對單體狀況下,若是是多個數據庫,主從備份,讀寫分離,那麼就會可能形成事務不一致的狀況,那麼什麼事分佈式事務,分佈式mysql
事務又該如何解決呢?sql
本地事務:本地事務的優勢就是支持嚴格的ACID特性,高效,可靠,狀態能夠只在資源管理器中維護,並且應用編程模型簡單。數據庫
全局事務:當事務由全局事務管理器進行全局管理時成爲全局事務,事務管理器負責管理全局的事務狀態和參與的資源,協同資源的一致提交回滾。編程
兩階段事務:兩階段事務提交採用的是X/OPEN組織所定義的DTP模型,經過抽象出來的AP
, TM
, RM
的概念能夠保證事務的強一致性。 其中TM
和RM
間採用XA
的協議進行雙向通訊。 與傳統的本地事務相比,網絡
XA事務增長了prepare階段,數據庫除了被動接受提交指令外,還能夠反向通知調用方事務是否能夠被提交。 所以TM
能夠收集全部分支事務的prepare結果,最後進行原子的提交,保證事務的強一致性。異步
BASE理論:BA指的是基本業務可用性,支持分區失敗,S表示柔性狀態,也就是容許短期內不一樣步,E表示最終一致性,數據最終是一致的,可是實時是不一致的。原子性和持久性必須從根本上保障,爲了可用性、性能和服務降級的須要,只有下降一致性和隔離性的要求。分佈式
CAP定理:對於共享數據系統,最多隻能同時擁有CAP其中的兩個,任意兩個都有其適應的場景,真是的業務系統中一般是ACID與CAP的混合體。分佈式系統中最重要的是知足業務需求,而不是追求高度抽象,絕對的系統特性。C表示一致性,也就是全部用戶看到的數據是同樣的。性能
A表示可用性,是指總能找到一個可用的數據副本。P表示分區容錯性,可以容忍網絡中斷等故障。編碼
兩階段提交其實比較簡單,這邊有兩個資源提供準備和提交兩個接口。設計
因爲隔離性互斥的要求,在事務執行過程當中,全部的資源都是被鎖定的,這種狀況只適合執行時間肯定的短事務。 可是爲了保證分佈式事務的一致性,大都是採用串行化的隔離級別來保證事務一致性,這樣會下降系統的吞吐。
但由於2PC的協議成本比較高,又有全局鎖的問題,性能會比較差。 如今你們基本上不會採用這種強一致解決方案。
TCC名字的由來是其中包含了 try, confirm, cancel三個操做。
與兩階段提交相比,TCC位於業務服務層, 沒有單獨的準備階段,Try操做能夠靈活選擇業務資源鎖的粒度。TCC是經過最終一致性來解決系統性能問題的這個設計,對咱們設計抉擇有很大的啓發。 有些時候系統的技術問題是能夠經過業務建模的方式來解決的。
Saga這個概念來源於三十多年前的一篇數據庫論文Sagas ,一個Saga事務是一個有多個短時事務組成的長時的事務。 在分佈式事務場景下,咱們把一個Saga分佈式事務看作是一個由多個本地事務組成的事務,每一個本地事務都有一個與之對應的補償事務。
在Saga事務的執行過程當中,若是某一步執行出現異常,Saga事務會被終止,同時會調用對應的補償事務完成相關的恢復操做,這樣保證Saga相關的本地事務要麼都是執行成功,要麼經過補償恢復成爲事務執行以前的狀態。
Saga定義了一個事務中的每一個子事務都有一個與之對應的反向補償操做。由Saga事務管理器根據程序執行結果生成一張有向無環圖,並在須要執行回滾操做時,根據該圖依次按照相反的順序調用反向補償操做。Saga事務管理器只用於控制什麼時候重試,什麼時候補償,
並不負責補償的內容,補償的具體操做須要由開發者自行提供。
SAGA能夠看作一個異步的、利用隊列實現的補償事務。
其適用於無需立刻返回業務發起方最終狀態的場景,例如:你的請求已提交,請稍後查詢或留意通知 之類。
將上述補償事務的場景用SAGA改寫,其流程以下:
以上爲成功的流程,若現金服務扣除金額失敗,那麼,最後一步訂單服務將會更新訂單狀態爲失敗。
其業務編碼工做量比補償事務多一點,包括如下內容:
但其相對於補償事務形態有性能上的優點,全部的本地子事務執行過程當中,都無需等待其調用的子事務執行,減小了加鎖的時間,這在事務流程較多較長的業務中性能優點更爲明顯。同時,其利用隊列進行進行通信,具備削峯填谷的做用。
所以該形式適用於不須要同步返回發起方執行最終結果、能夠進行補償、對性能要求較高、不介意額外編碼的業務場景。
但固然SAGA也能夠進行稍微改造,變成與TCC相似、能夠進行資源預留的形態。
基於消息實現的事務適用於分佈式事務的提交或回滾只取決於事務發起方的業務需求,其餘數據源的數據變動跟隨發起方進行的業務場景。
舉個例子,假設存在業務規則:某筆訂單成功後,爲用戶加必定的積分。
在這條規則裏,管理訂單數據源的服務爲事務發起方,管理積分數據源的服務爲事務跟隨者。
從這個過程能夠看到,基於消息隊列實現的事務存在如下操做:
咱們能夠看到它的總體流程是比較簡單的,同時業務開發工做量也不大:
能夠看到該事務形態過程簡單,性能消耗小,發起方與跟隨方之間的流量峯谷可使用隊列填平,同時業務開發工做量也基本與單機事務沒有差異,都不須要編寫反向的業務邏輯過程。所以基於消息隊列實現的事務是咱們除了單機事務外最優先考慮使用的形態。