三階段提交(3PC)是二階段提交(2PC)的改進版本,三階段提交協議主要是為了解決兩階段提交協議的阻塞問題,2pc存在的問題是當協調者崩潰時,參與者不能做出最后的選擇,因此參與者可能在協調者恢復之前保持阻塞,三階段提交(Three-phase commit),是二階段提交(2PC)的改進版本,
三階段提交3PC
與兩階段提交不同的是,三階段提交有兩個改動點:
- 引入超時機制,同時在協調者和參與者中都引入超時機制;
- 在第一階段和第二階段中插入一個準備階段,保證了在最后提交階段之前各參與節點的狀態是一致的,
3PC把2PC的準備階段再次一分為二,這樣三階段提交就有CanCommit、PreCommit、DoCommit三個階段,
CanCommit階段
之前2PC的一階段是本地事務執行結束后,最后不Commit,等其它服務都執行結束并回傳Yes,由協調者發生commit才真正執行commit,而這里的CanCommit指的是 嘗試獲取資料庫鎖 如果可以,就回傳Yes,這階段主要分為2步
- 事務詢問:協調者向參與者發送CanCommit請求,詢問是否可以執行事務提交操作,然后開始等待參與者的回應;
- 回應反饋:參與者接到CanCommit請求之后,正常情況下,如果其自身認為可以順利執行事務,則回傳Yes回應,并進入預備狀態,否則反饋No,

PreCommit階段
在階段一中,如果所有的參與者都回傳Yes的話,那么就會進入PreCommit階段進行事務預提交,這里的PreCommit階段 跟上面的第一階段是差不多的,只不過這里協調者和參與者都引入了超時機制 (2PC中只有協調者可以超時,參與者沒有超時機制),主要包含兩個步驟:
- 事務預提交:參與者接收到PreCommit請求后,會執行事務操作,并將undo和redo資訊記錄到事務日志中,
- 回應反饋:如果參與者成功的執行了事務操作,則回傳ACK回應,同時開始等待最終指令,

假如有任何一個參與者向協調者發送了No回應,或者等待超時之后,協調者都沒有接到參與者的回應,那么就執行事務的中斷:
- 發送中斷請求:協調者向所有參與者發送abort請求,
- 中斷事務:參與者收到來自協調者的abort請求之后(或超時之后,仍未收到協調者的請求),執行事務的中斷,

DoCommit階段
該階段進行真正的事務提交,也可以分為以下兩種情況,
執行提交,發送提交請求 協調接收到參與者發送的ACK回應,那么他將從預提交狀態進入到提交狀態,并向所有參與者發送doCommit請求,
- 事務提交:參與者接收到doCommit請求之后,執行正式的事務提交,并在完成事務提交之后釋放所有事務資源,
- 回應反饋:事務提交完之后,向協調者發送Ack回應,
- 完成事務:協調者接收到所有參與者的ack回應之后,完成事務,

中斷事務,協調者沒有接收到參與者發送的ACK回應(可能是接受者發送的不是ACK回應,也可能回應超時),那么就會執行中斷事務,
- 發送中斷請求:協調者向所有參與者發送abort請求
- 事務回滾:參與者接收到abort請求之后,利用其在階段二記錄的undo資訊來執行事務的回滾操作,并在完成回滾之后釋放所有的事務資源,
- 反饋結果:參與者完成事務回滾之后,向協調者發送ACK訊息
- 中斷事務:協調者接收到參與者反饋的ACK訊息之后,執行事務的中斷,

總結
相對于2PC,3PC主要解決的單點故障問題,并減少阻塞,因為一旦參與者無法及時收到來自協調者的資訊之后,他會默認執行commit,而不會一直持有事務資源并處于阻塞狀態,但是這種機制也會導致資料一致性問題,因為,由于網路原因,協調者發送的abort回應沒有及時被參與者接收到,那么參與者在等待超時之后執行了commit操作,這樣就和其他接到abort命令并執行回滾的參與者之間存在資料不一致的情況,
在2PC中一個參與者的狀態只有它自己和協調者知曉,假如協調者提議后自身宕機,在協調者備份啟用前一個參與者又宕機,其他參與者就會進入既不能回滾、又不能強制commit的阻塞狀態,直到參與者宕機恢復,
參與者如果在不同階段宕機,我們來看看3PC如何應對:
- 階段1: 協調者或協調者備份未收到宕機參與者的vote,直接中止事務;宕機的參與者恢復后,讀取logging發現未發出贊成vote,自行中止該次事務
- 階段2: 協調者未收到宕機參與者的precommit ACK,但因為之前已經收到了宕機參與者的贊成反饋(不然也不會進入到階段2),協調者進行commit;協調者備份可以通過問詢其他參與者獲得這些資訊,程序同理;宕機的參與者恢復后發現收到precommit或已經發出贊成vote,則自行commit該次事務
- 階段3: 即便協調者或協調者備份未收到宕機參與者t的commit ACK,也結束該次事務;宕機的參與者恢復后發現收到commit或者precommit,也將自行commit該次事務,
我是御狐神,歡迎大家關注我的微信公眾號:wzm2zsd

本文最先發布至微信公眾號,著作權所有,禁止轉載!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/345478.html
標籤:Java
