1. 程式人生 > 其它 >分散式事物之三階段事物提交

分散式事物之三階段事物提交

三階段提交協議(3PC:Three-Phrase Commit)

  針對兩階段提交存在的問題,三階段提交協議通過引入一個“預詢盤”階段,以及超時策略來減少整個叢集的阻塞時間,提升系統性能。三階段提交的三個階段分別為:can_commit,pre_commit,do_commit。

第一階段:can_commit

  該階段協調者會去詢問各個參與者是否能夠正常執行事務,參與者根據自身情況回覆一個預估值,相對於真正的執行事務,這個過程是輕量的,具體步驟如下:

  1. 協調者向各個參與者傳送事務詢問通知,詢問是否可以執行事務操作,並等待回覆
  2. 各個參與者依據自身狀況回覆一個預估值,如果預估自己能夠正常執行事務就返回確定資訊,並進入預備狀態,否則返回否定資訊

第二階段:pre_commit

本階段協調者會根據第一階段的詢盤結果採取相應操作,詢盤結果主要有三種:

  1. 所有的參與者都返回確定資訊
  2. 一個或多個參與者返回否定資訊
  3. 協調者等待超時

針對第一種情況,協調者會向所有參與者傳送事務執行請求,具體步驟如下:

  1. 協調者向所有的事務參與者傳送事務執行通知
  2. 參與者收到通知後,執行事務,但不提交
  3. 參與者將事務執行情況返回給客戶端

在上面的步驟中,如果參與者等待超時,則會中斷事務。針對第二、三種情況,協調者認為事務無法正常執行,於是向各個參與者發出abort通知,請求退出預備狀態,具體步驟如下:

  1. 協調者向所有事務參與者傳送abort通知
  2. 參與者收到通知後,中斷事務

第三階段:do_commit

  如果第二階段事務未中斷,那麼本階段協調者將會依據事務執行返回的結果來決定提交或回滾事務,分為三種情況:

  1. 所有的參與者都能正常執行事務
  2. 一個或多個參與者執行事務失敗
  3. 協調者等待超時

針對第一種情況,協調者向各個參與者發起事務提交請求,具體步驟如下:

  1. 協調者向所有參與者傳送事務commit通知
  2. 所有參與者在收到通知之後執行commit操作,並釋放佔有的資源
  3. 參與者向協調者反饋事務提交結果

針對第二、三種情況,協調者認為事務無法正常執行,於是向各個參與者傳送事務回滾請求,具體步驟如下:

  1. 協調者向所有參與者傳送事務rollback通知
  2. 所有參與者在收到通知之後執行rollback操作,並釋放佔有的資源
  3. 參與者向協調者反饋事務提交結果

  在本階段如果因為協調者或網路問題,導致參與者遲遲不能收到來自協調者的commit或rollback請求,那麼參與者將不會如兩階段提交中那樣陷入阻塞,而是等待超時後繼續commit。相對於兩階段提交雖然降低了同步阻塞,但仍然無法避免資料的不一致性。

  在分散式資料庫中,如果期望達到資料的強一致性,那麼服務基本沒有可用性可言,這也是為什麼許多分散式資料庫提供了跨庫事務,但也只是個擺設的原因,在實際應用中我們更多追求的是資料的弱一致性或最終一致性,為了強一致性而丟棄可用性是不可取的。