跨行轉帳問題是一個典型的分佈式事務,用戶A向B的一個轉帳1000,要進行A的餘額-1000,B的餘額+1000,顯然必須保證這兩個操做的事務性。
相似的還有,電商系統中,當有用戶下單後,除了在訂單表插入記,還要在商品表更新庫存等,特別是隨着微服務架構的流行,分佈式事務的場景更變得更廣泛。算法
二階段提交協議(2PC)一般用來保證數據的強一致性,二階段提交協議(2PC)中存在兩種類型的節點:協調節點和數據節點(或稱協調者與參與者),數據節點能夠說是數據在多個節點的備份,協調節點用戶協調管理多個數據節點在事務操做中數據的一致性問題;
2PC(Two Phase Commit)協議一般分爲兩個階段進行,提交請求階段(Commit Request Phase)或稱投票階段(Voting phase)、與提交階段(Commit Phase);
1.提交請求階段(Commit Request Phase),協調者發送請求給參與者,通知參與者提交或取消事務,參與者進入投票過程,每一個參與者回覆給協調者本身的投票:贊成(事務在本地執行成功)或取消(事務本地執行失敗)。
2.提交階段(Commit Phase),協調者對上一階段參與者的投票結果進行表決,當全部投票爲「贊成」時提交提交事務,否者停止事務,並通知參與者,參與者接到通知後執行相應的操做。
2PC(TWO Phase Commit)假定節點沒有崩潰、任意兩個節點的網絡都是正常連通的、在寫日誌的過程當中數據不會丟失的前提下。網絡
兩階段提交協議是協調全部分佈式原子事務參與者,並決定提交或取消(回滾)的分佈式算法。架構
1.協議參與者分佈式
在兩階段提交協議中,系統通常包含兩類機器(或節點):一類爲協調者(coordinator),一般一個系統中只有一個;另外一類爲事務參與者(participants,cohorts或workers),通常包含多個,在數據存儲系統中能夠理解爲數據副本的個數。協議中假設每一個節點都會記錄寫前日誌(write-ahead log)並持久性存儲,即便節點發生故障日誌也不會丟失。協議中同時假設節點不會發生永久性故障並且任意兩個節點均可以互相通訊。微服務
2.兩個階段的執行日誌
1.請求階段(commit-request phase,或稱表決階段,voting phase)
在請求階段,協調者將通知事務參與者準備提交或取消事務,而後進入表決過程。
在表決過程當中,參與者將告知協調者本身的決策:贊成(事務參與者本地做業執行成功)或取消(本地做業執行故障)。orm
2.提交階段(commit phase)
在該階段,協調者將基於第一個階段的投票結果進行決策:提交或取消。
當且僅當全部的參與者贊成提交事務協調者才通知全部的參與者提交事務,不然協調者將通知全部的參與者取消事務。
參與者在接收到協調者發來的消息後將執行響應的操做。cdn
(3)兩階段提交的缺點blog
1.同步阻塞問題。執行過程當中,全部參與節點都是事務阻塞型的。
當參與者佔有公共資源時,其餘第三方節點訪問公共資源不得不處於阻塞狀態。事務
2.單點故障。因爲協調者的重要性,一旦協調者發生故障。
參與者會一直阻塞下去。尤爲在第二階段,協調者發生故障,那麼全部的參與者還都處於鎖定事務資源的狀態中,而沒法繼續完成事務操做。(若是是協調者掛掉,能夠從新選舉一個協調者,可是沒法解決由於協調者宕機致使的參與者處於阻塞狀態的問題)
3.數據不一致。在二階段提交的階段二中,當協調者向參與者發送commit請求以後,發生了局部網絡異常或者在發送commit請求過程當中協調者發生了故障,這回致使只有一部分參與者接受到了commit請求。
而在這部分參與者接到commit請求以後就會執行commit操做。可是其餘部分未接到commit請求的機器則沒法執行事務提交。因而整個分佈式系統便出現了數據部一致性的現象。
(4)兩階段提交沒法解決的問題
當協調者出錯,同時參與者也出錯時,兩階段沒法保證事務執行的完整性。
考慮協調者再發出commit消息以後宕機,而惟一接收到這條消息的參與者同時也宕機了。
那麼即便協調者經過選舉協議產生了新的協調者,這條事務的狀態也是不肯定的,沒人知道事務是否被已經提交。