爲了彌補二階段提交的缺點,研究者們在他的基礎上,提出了三階段提交。
3PC(三階段提交)
3PC,全稱 “three phase commit”,是 2PC 的改進版,其將 2PC 的 “提交事務請求” 過程一分爲二,總共形成了 3 個部分:
- CanCommit
- PreCommit
- do Commit
階段一:CanCommit
- 事務詢問:協調者向所有的參與者發送一個包含事務內容的 canCommit 請求,詢問是否可以執行事務提交操作,並開始等待各參與者的響應。
- 各參與者向協調者反饋事務詢問的響應:參與者接收來自協調者的 canCommit 請求,如果參與者認爲自己可以順利執行事務,就返回 Yes,否則反饋 No 響應。
階段二:PreCommit
協調者在得到所有參與者的響應之後,會根據結果執行2種操作:執行事務預提交,或者中斷事務。
執行事務預提交分爲 3 個步驟:
- 發送預提交請求:協調者向所有參與者節點發出 preCommit 的請求,並進入 prepared 狀態。
- 事務預提交:參與者受到 preCommit 請求後,會執行事務操作,對應 2PC 中的 “執行事務”,也會 Undo 和 Redo 信息記錄到事務日誌中。
- 各參與者向協調者反饋事務執行的結果:如果參與者成功執行了事務,就反饋 Ack 響應,同時等待指令:提交(commit) 或終止(abor)。
中斷事務也分爲2個步驟:
- 發送中斷請求:協調者向所有參與者節點發出 abort 請求 。
- 中斷事務:參與者如果收到 abort 請求或者超時了,都會中斷事務。
階段三:do Commit
該階段做真正的提交,同樣也會出現兩種情況:
執行提交
- 發送提交請求:進入這一階段,如果協調者正常工作,並且接收到了所有協調者的 Ack 響應,那麼協調者將從 “預提交” 狀態變爲 “提交” 狀態,並向所有的參與者發送 doCommit 請求 。
- 事務提交:參與者收到 doCommit 請求後,會正式執行事務提交操作,並在完成之後釋放在整個事務執行期間佔用的事務資源。
- 反饋事務提交結果:參與者完成事務提交後,向協調者發送 Ack 消息。
- 完成事務:協調者接收到所有參與者反饋的 Ack 消息後,完成事務。
中斷事務
假設有任何參與者反饋了 no 響應,或者超時了,就中斷事務。
- 發送中斷請求:協調者向所有的參與者節點發送 abort 請求。
- 事務回滾:參與者接收到 abort 請求後,會利用其在二階段記錄的 undo 信息來執行事務回滾操作,並在完成回滾之後釋放整個事務執行期間佔用的資源。
- 反饋事務回滾結果:參與者在完成事務回滾之後,想協調者發送 Ack 消息。
- 中斷事務:協調者接收到所有的 Ack 消息後,中斷事務。
一旦進入階段三,可能會出現 2 種故障:
- 協調者出現問題
- 協調者和參與者之間的網絡故障
一段出現了任一一種情況,最終都會導致參與者無法收到 doCommit 請求或者 abort 請求,針對這種情況,參與者都會在等待超時之後,繼續進行事務提交。
- 優點:相比較 2PC,最大的優點是減少了參與者的阻塞範圍(第一個階段是不阻塞的),並且能夠在單點故障後繼續達成一致(2PC 在提交階段會出現此問題,而 3PC 會根據協調者的狀態進行回滾或者提交)。
- 缺點:如果參與者收到了 preCommit 消息後,出現了網絡分區,那麼參與者等待超時後,都會進行事務的提交,這必然會出現事務不一致的問題。