1、2PC協議
2PC 是二階段提交(Two-phase Commit)的縮寫,顧名思義,這個協議分兩階段完成。第一個階段是准備階段,第二個階段是提交階段,准備階段和提交階段都是由事務管理器(協調者)發起的,協調的對象是資源管理器(參與者)。二階段提交協議的概念來自 X/Open 組織提出的分布式事務的規范 XA 協議,協議主要定義了(全局)事務管理器和(局部)資源管理器之間的接口。XA 接口是雙向的系統接口,在事務管理器以及一個或多個資源管理器之間形成通信橋梁。Java 平台上的事務規范 JTA(Java Transaction API)提供了對 XA 事務的支持,它要求所有需要被分布式事務管理的資源(由不同廠商實現)都必須實現規定接口(XAResource 中的 prepare、commit 和 rollback 等)。
①准備階段:協調者向參與者發起指令,參與者評估自己的狀態,如果參與者評估指令可以完成,參與者會寫 redo 和 undo 日志,然后鎖定資源,執行操作,但是並不提交。
②提交階段:如果每個參與者明確返回准備成功,也就是預留資源和執行操作成功,協調者向參與者發起提交指令,參與者提交資源變更的事務,釋放鎖定的資源;如果任何一個參與者明確返回准備失敗,也就是預留資源或者執行操作失敗,協調者向參與者發起中止指令,參與者取消已經變更的事務,執行 undo 日志,釋放鎖定的資源。
兩階段提交協議在准備階段鎖定資源,是一個重量級的操作,並能保證強一致性,但是實現起來復雜、成本較高,不夠靈活,更重要的是它有如下致命的問題:
阻塞:從上面的描述來看,對於任何一次指令必須收到明確的響應,才會繼續做下一步,否則處於阻塞狀態,占用的資源被一直鎖定,不會被釋放。
單點故障:如果協調者宕機,參與者沒有了協調者指揮,會一直阻塞,盡管可以通過選舉新的協調者替代原有協調者,但是如果之前協調者在發送一個提交指令后宕機,而提交指令僅僅被一個參與者接受,並且參與者接收后也宕機,新上任的協調者無法處理這種情況。
腦裂:協調者發送提交指令,有的參與者接收到執行了事務,有的參與者沒有接收到事務,就沒有執行事務,多個參與者之間是不一致的。
2、3PC協議
三階段提交協議(3PC 協議)是兩階段提交協議的改進版本。它通過超時機制解決了阻塞的問題,並且把兩個階段增加為三個階段:
①詢問階段:協調者詢問參與者是否可以完成指令,協調者只需要回答是還是不是,而不需要做真正的操作,這個階段參與者在等待超時后會自動中止。
②准備階段:如果在詢問階段所有的參與者都返回可以執行操作,協調者向參與者發送預執行請求,然后參與者寫 redo 和 undo 日志,鎖定資源,執行操作,但是不提交操作;如果在詢問階段任何參與者返回不能執行操作的結果,則協調者向參與者發送中止請求,這里的邏輯與兩階段提交協議的的准備階段是相似的,這個階段參與者在等待超時后會自動提交。
③提交階段:如果每個參與者在准備階段返回准備成功,也就是預留資源和執行操作成功,協調者向參與者發起提交指令,參與者提交資源變更的事務,釋放鎖定的資源;如果任何一個參與者返回准備失敗,也就是預留資源或者執行操作失敗,協調者向參與者發起中止指令,參與者取消已經變更的事務,執行 undo 日志,釋放鎖定的資源,這里的邏輯與兩階段提交協議的提交階段一致。
詢問階段:詢問階段可以確保盡可能早的發現無法執行操作而需要中止的行為,但是它並不能發現所有的這種行為,只會減少這種情況的發生。
等待超時:如果在詢問階段等待超時,則自動中止;如果在准備階段之后等待超時,則自動提交。這也是根據概率統計上的正確性最大。
3、TCC協議
TCC 將事務的提交過程分為 try-confirm-cancel(實際上 TCC 就是 try、confirm、cancel 的簡稱) 三個階段:
try:完成業務檢查、預留業務資源
confirm:使用預留的資源執行業務操作(需要保證冪等性)
cancel:取消執行業務操作,釋放預留的資源(需要保證冪等性)
①事務發起方向事務協調器發起事務請求,事務協調器調用所有事務參與者的 try 方法完成資源的預留,這時候並沒有真正執行業務,而是為后面具體要執行的業務預留資源,這里完成了一階段。
②如果事務協調器發現有參與者的 try 方法預留資源時候發現資源不夠,則調用參與方的 cancel 方法回滾預留的資源,需要注意 cancel 方法需要實現業務冪等,因為有可能調用失敗(比如網絡原因參與者接受到了請求,但是由於網絡原因事務協調器沒有接受到回執)會重試。
③如果事務協調器發現所有參與者的 try 方法返回都 OK,則事務協調器調用所有參與者的 confirm 方法,不做資源檢查,直接進行具體的業務操作。
④如果協調器發現所有參與者的 confirm 方法都 OK 了,則分布式事務結束。
⑤如果協調器發現有些參與者的 confirm 方法失敗了,或者由於網絡原因沒有收到回執,則協調器會進行重試。這里如果重試一定次數后還是失敗,會做事務補償。