淺談分布式事務

(轉)### 什么是事務
事務(Transaction)是數據庫系統中一系列操作的一個邏輯單元,所有操作要么全部成功要么全部失敗。

ACID

說起事務,就不得不談事務的四大特性ACID

  • 原子性(Atomicity)
    一個是事務的所有操作,要么全部成功,要么全部失敗,不會結束在中間的某個環節。事務在執行過程中發生錯誤或者異常,會恢復(Rollback)到事務開始前的狀態,就像這個事務沒有執行過一樣。比如轉賬要么全部成功,要么全部失敗,不可能一個賬號扣了錢,另一個賬號沒加錢,不滿足原子性。
  • 一致性(Consistency)
    事務確保數據從一個valid狀態轉換到另一個valid狀態。這里的一致性強調的是事務操作使得數據一直處于符合狀態預定規則。比如轉賬,事務前兩個賬號一共1000元,轉賬后也必須是1000元。
  • 隔離性(Isolation)
    事務通常是并發執行的,是同時對數據庫進行讀寫和修改的,隔離性要求多個事務并發執行對數據庫的影響看起來跟串行一樣。通常為了提高1并發度,我們互弱化1事務并發時對數據的一致性要求,允許若干種數據不一致的現象,這就是不同的事務隔離級別:包括讀未提交(Read uncommitted)、讀提交(Read committed)、可重復度(repeatable read)、串行化(Serializable)。嚴格來說,只有最高級別的串行化才嚴格符合隔離性。
  • 持久性(Durability)
    事務處理完成后,對數據的修改是永久的,及時系統出現故障也不會丟失。
    ACID都是為了保障數據的一致性,不滿足ACID則可能會出現數據不一致。

分布式事務

現階段業務發展迅猛,數據往往超出單機數據庫所能處理的極限,會遇到性能的瓶頸。而應用層面微服務架構越來越流行,從原來的單體應用拆分成一個個獨立的微服務,當應用通過一組微服務來協助完成時,對數據的一致性就需要分布式事務來保證。
對數據庫通常采用垂直拆分和水平數據分片,將數據拆分到多個不同的數據節點上。如果一個事務涉及了多個不同分片節點則產生了分布式事務。
常見的幾種分布式事務實現:

  • 基于XA協議的2pc

兩階段提交(2pc)應該屬于被提到最多的分布式事務實現方案。該協議(Two-Phase-Commit)主要定義了事務管理器(Transaction Manager)和資源管理器(Resource Manager)之間的接口。
兩階段提交將提交過程分為兩個階段,在第一階段,協調者詢問所有的參與者是否可以提交事務,所有參與者向協調者投票。第二階段,協調者根據所有參與者的投票結果做出事務可以全局提交或者回滾的決定,并通知參與者執行該決定。

  • 2pc的缺點
    2pc雖然保證了提交的原子性,但缺點也很明顯:
    1、同步阻塞。執行過程中,所有參與的節點都是事務阻塞型的。當參與者占有資源時,其他第三方節點訪問資源不得不處于阻塞狀態。
    2、單點故障。由于協調者的重要性,一旦協調者發生故障,參與者會一直阻塞下去。尤其第二階段,所有參與者會處于鎖定事務資源的狀態,從而無法繼續完成其他事務操作。
    2pc的協調者和每個參與者只要有兩輪消息交互,寫日志等,過程又是阻塞狀態,性能低下。

  • 2pc的一致性
    從隔離性的角度來說,2pc只能算是最終一致性,算不得強一致性。

  • MySQL對XA支持問題
    1、prepare未寫入binlog,若主機宕機切換回來后丟失prepare
    2、客戶端退出或者主機宕機,MySQL會自動那個回滾。

  • TCC

TCC事務機制相對于XA的2pc機制,其特征在于不依賴資源管理器(RM)對XA的支持,同時通過對業務邏輯的調度來實現分布式事務。
TCC型事務(Trying/Confirming/Canceling)

  • TRYING階段主要是對業務系統做檢測及資源預留。
  • CONFIRMING階段主要是對業務系統做確認提交,TRING階段執行成功并開始執行CONFIRMING階段時,默認是一定成功的,即:TRING成功,CONFIRMING成功。
  • CANCELING階段主要是在業務執行階段執行錯誤,需要回滾的狀態下執行的業務取消和預留資源的釋放
  • TCC和2pc的區別

2pc的一個完成的事務生命周期:begin->業務邏輯->prepare->commit。TCC的一個完整的事務生命周期:begin->業務邏輯(try業務)->commit(confirm業務)。
TCC的Tring/Confirming/Canceling三個接口針對每個事物都需要用戶自己來實現,對用戶不太友好,增加開發工作量。

  • SAGA

SAGA的核心思想是將分布式事務分成多個本地事務,即主事務和從事務。本地事務·先提交,然后通過消息通知從事務,從事務從消息中獲取信息進行本地提交。這是一種異步提交機制,只能保證最終一致性,但可用性高,不會因為故障而阻塞。
但實際上并沒有解決分布式問題。為了使第一個事務部涉及分布式操作,消息隊列必須與第一個事務使用一套存儲資源,同理為了使第二個事務是本地的,又需要和第二個事務存儲在一起,這樣本質上沒有規避分布式事務。

  • 最大努力提交

1、與2pc相比,省去prepare,本質上屬于1pc
2、commit推遲到最后一步執行
優點性能非常好,且對用戶透明,缺點是可能存在部分提交成功部分失敗的情況。而且對于已經成功的commit無法rollback。但是由于將相對容易出錯的sql執行階段先執行,commit推遲到最后一起執行,相當于將可能出錯的窗口縮小到最后的commit階段,而commit之前的出錯可以正常回滾。
該模型適合絕大多數不涉及金錢來往的業務,在性能和一致性之間有一個較好的平衡。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容