1. 程式人生 > >end's coding life

end's coding life

一、事務

定義

事務提供一種機制將一個活動涉及的所有操作納入到一個不可分割的執行單元,組成事務的所有操作只有在所有操作均能正常執行的情況下方能提交,只要其中任一操作執行失敗,都將導致整個事務的回滾。簡單地說,事務提供一種“要麼什麼都不做,要麼做全套(All or Nothing)”機制。

特性

說到資料庫事務就不得不說,資料庫事務中的四大特性,ACID:

  • A:原子性(Atomicity) 
    一個事務(transaction)中的所有操作,要麼全部完成,要麼全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。 
    就像你買東西要麼交錢收貨一起都執行,要麼要是發不出貨,就退錢。
  • C:一致性(Consistency) 
    事務的一致性指的是在一個事務執行之前和執行之後資料庫都必須處於一致性狀態。如果事務成功地完成,那麼系統中所有變化將正確地應用,系統處於有效狀態。如果在事務中出現錯誤,那麼系統中的所有變化將自動地回滾,系統返回到原始狀態。
  • I:隔離性(Isolation) 
    指的是在併發環境中,當不同的事務同時操縱相同的資料時,每個事務都有各自的完整資料空間。由併發事務所做的修改必須與任何其他併發事務所做的修改隔離。事務檢視資料更新時,資料所處的狀態要麼是另一事務修改它之前的狀態,要麼是另一事務修改它之後的狀態,事務不會檢視到中間狀態的資料。 
    打個比方,你買東西這個事情,是不影響其他人的。
  • D:永續性(Durability) 
    指的是隻要事務成功結束,它對資料庫所做的更新就必須永久儲存下來。即使發生系統崩潰,重新啟動資料庫系統後,資料庫還能恢復到事務成功結束時的狀態。 
    打個比方,你買東西的時候需要記錄在賬本上,即使老闆忘記了那也有據可查。

二、分散式事務

定義

分散式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分散式系統的不同節點之上。簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的伺服器上,且屬於不同的應用,分散式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分散式事務就是為了保證不同資料庫的資料一致性。

原因

  • service多個節點

隨著網際網路快速發展,微服務,SOA等服務架構模式正在被大規模的使用,舉個簡單的例子,一個公司之內,使用者的資產可能分為好多個部分,比如餘額,積分,優惠券等等。在公司內部有可能積分功能由一個微服務團隊維護,優惠券又是另外的團隊維護 
這樣的話就無法保證積分扣減了之後,優惠券能否扣減成功。

  • resource多個節點

同樣的,網際網路發展得太快了,我們的Mysql一般來說裝千萬級的資料就得進行分庫分表,對於一個支付寶的轉賬業務來說,你給的朋友轉錢,有可能你的資料庫是在北京,而你的朋友的錢是存在上海,所以我們依然無法保證他們能同時成功。

理論基礎

CAP

  • C 一致性
  • A 可用性
  • P 分割槽容錯性

無法同時滿足,P是無法避免的,所以一般選擇CP或AP。 
P的概率非常低,大部分時間還是要同時考慮C和A的。 
忽略了網路延遲,從節點A複製到節點B,但是在現實中這個是明顯不可能的,所以總會有一定的時間是不一致。

BASE

BASE 是 Basically Available(基本可用)、Soft state(軟狀態)和 Eventually consistent (最終一致性)三個短語的縮寫。是對CAP中AP的一個擴充套件

  1. 基本可用:分散式系統在出現故障時,允許損失部分可用功能,保證核心功能可用。
  2. 軟狀態:允許系統中存在中間狀態,這個狀態不影響系統可用性,這裡指的是CAP中的不一致。
  3. 最終一致:最終一致是指經過一段時間後,所有節點資料都將會達到一致。

BASE解決了CAP中理論沒有網路延遲,在BASE中用軟狀態和最終一致,保證了延遲後的一致性。BASE和 ACID 是相反的,它完全不同於ACID的強一致性模型,而是通過犧牲強一致性來獲得可用性,並允許資料在一段時間內是不一致的,但最終達到一致狀態

方案

2PC

優點: 儘量保證了資料的強一致,實現成本較低,在各大主流資料庫都有自己實現,對於MySQL是從5.5開始支援。 
缺點: 
單點問題:事務管理器在整個流程中扮演的角色很關鍵,如果其宕機,比如在第一階段已經完成,在第二階段正準備提交的時候事務管理器宕機,資源管理器就會一直阻塞,導致資料庫無法使用。 
同步阻塞:在準備就緒之後,資源管理器中的資源一直處於阻塞,直到提交完成,釋放資源。 
資料不一致:兩階段提交協議雖然為分散式資料強一致性所設計,但仍然存在資料不一致性的可能,比如在第二階段中,假設協調者發出了事務commit的通知,但是因為網路問題該通知僅被一部分參與者所收到並執行了commit操作,其餘的參與者則因為沒有收到通知一直處於阻塞狀態,這時候就產生了資料的不一致性。 
總的來說,XA協議比較簡單,成本較低,但是其單點問題,以及不能支援高併發(由於同步阻塞)依然是其最大的弱點。

TCC

  • Try階段:嘗試執行,完成所有業務檢查(一致性),預留必須業務資源(準隔離性)
  • Confirm階段:確認執行真正執行業務,不作任何業務檢查,只使用Try階段預留的業務資源,要求具備冪等設計,Confirm失敗後需要進行重試
  • Cancel階段:取消執行,釋放Try階段預留的業務資源 。Cancel階段的異常和Confirm階段異常處理方案基本上一致,失敗重試,要求冪等性

適用於:

  • 嚴格要求一致的業務
  • 執行時間短的業務

本地訊息表

基於BASE理論,最終一致性模型。通過訊息表、訊息佇列實現最終一致性。自動或人工干預異常情況,注意重試冪等性。 
適用於一致性要求不高的場景。 

MQ事務

實際是對本地訊息表方案的封裝,將訊息表存在了MQ內部。 
第一階段Prepared訊息,會拿到訊息的地址。 
第二階段執行本地事務。 
第三階段通過第一階段拿到的地址去訪問訊息,並修改狀態。訊息接受者就能使用這個訊息。 
如果確認訊息失敗,在RocketMq Broker中提供了定時掃描沒有更新狀態的訊息,如果有訊息沒有得到確認,會向訊息傳送者傳送訊息,來判斷是否提交,在rocketmq中是以listener的形式給傳送者,用來處理。 
如果消費超時,則需要一直重試,訊息接收端需要保證冪等。如果訊息消費失敗,這個就需要人工進行處理,因為這個概率較低,如果為了這種小概率時間而設計這個複雜的流程反而得不償失。 
RocketMq提供了上述功能。

Saga事務

其核心思想是將長事務拆分為多個本地短事務,由Saga事務協調器協調,如果正常結束那就正常完成,如果某個步驟失敗,則根據相反順序一次呼叫補償操作。 Saga的組成: 
每個Saga由一系列sub-transaction Ti 組成 每個Ti 都有對應的補償動作Ci,補償動作用於撤銷Ti造成的結果,這裡的每個T,都是一個本地事務。 可以看到,和TCC相比,Saga沒有“預留 try”動作,它的Ti就是直接提交到庫。 
Saga的執行順序有兩種: 
T1, T2, T3, ..., Tn 
T1, T2, ..., Tj, Cj,..., C2, C1,其中0 < j < n Saga定義了兩種恢復策略: 
向後恢復,即上面提到的第二種執行順序,其中j是發生錯誤的sub-transaction,這種做法的效果是撤銷掉之前所有成功的sub-transation,使得整個Saga的執行結果撤銷。 向前恢復,適用於必須要成功的場景,執行順序是類似於這樣的:T1, T2, ..., Tj(失敗), Tj(重試),..., Tn,其中j是發生錯誤的sub-transaction。該情況下不需要Ci。 
這裡要注意的是,在saga模式中不能保證隔離性,因為沒有鎖住資源,其他事務依然可以覆蓋或者影響當前事務。