前提
二階段提交算法的成立基於以下假設:
該分散式系統中,存在一個節點作為協調者(Coordinator),其他節點作為參與者(Cohorts)。且節點之間可以進行網路通信。
所有節點都採用預寫式日誌,且日誌被寫入後即被保持在可靠的存儲設備上,即使節點損壞不會導致日誌數據的消失。
所有節點不會永久性損壞,即使損壞後仍然可以恢復。
1.協調者
2.所有節點都採用預寫式日誌,且日誌被寫入後即被保持在可靠的存儲設備上,即使節點損壞不會導致日誌數據的消失。
3.所有節點不會永久性損壞,即使損壞後仍然可以恢復。
基本算法
以下對 二階段提交算法分階段進行說明。
第一階段提交請求階段
協調者節點向所有參與者節點詢問是否可以執行提交操作,並開始等待各參與者節點的回響。
參與者節點執行詢問發起為止的所有事務操作,並將Undo信息和Redo信息寫入日誌。
各參與者節點回響協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它返回一個"同意"訊息;如果參與者節點的事務操作實際執行失敗,則它返回一個"中止"訊息。
1.協調者節點向所有參與者節點詢問是否可以執行提交操作,並開始等待各參與者節點的回響。
2.參與者節點執行詢問發起為止的所有事務操作,並將Undo信息和Redo信息寫入日誌。
3.各參與者節點回響協調者節點發起的詢問。如果參與者節點的事務操作實際執行成功,則它返回一個"同意"訊息;如果參與者節點的事務操作實際執行失敗,則它返回一個"中止"訊息。
有時候,第一階段也被稱作 投票階段,即各參與者投票是否要繼續接下來的提交操作。
第二階段提交執行階段
成功
當協調者節點從所有參與者節點獲得的相應訊息都為"同意"時:
協調者節點向所有參與者節點發出"正式提交"的請求。
參與者節點正式完成操作,並釋放在整個事務期間內占用的資源。
參與者節點向協調者節點傳送"完成"訊息。
協調者節點收到所有參與者節點反饋的"完成"訊息後,完成事務。
1.協調者節點向所有參與者節點發出"正式提交"的請求。
2.參與者節點正式完成操作,並釋放在整個事務期間內占用的資源。
3.參與者節點向協調者節點傳送"完成"訊息。
4.協調者節點收到所有參與者節點反饋的"完成"訊息後,完成事務。
失敗
如果任一參與者節點在第一階段返回的回響訊息為"終止",或者 協調者節點在第一階段的詢問逾時之前無法獲取所有參與者節點的回響訊息時:
協調者節點向所有參與者節點發出"回滾操作"的請求。
參與者節點利用之前寫入的Undo信息執行回滾,並釋放在整個事務期間內占用的資源。
參與者節點向協調者節點傳送"回滾完成"訊息。
協調者節點收到所有參與者節點反饋的"回滾完成"訊息後,取消事務。
1.協調者節點向所有參與者節點發出"回滾操作"的請求。
2.參與者節點利用之前寫入的Undo信息執行回滾,並釋放在整個事務期間內占用的資源。
3.參與者節點向協調者節點傳送"回滾完成"訊息。
4.協調者節點收到所有參與者節點反饋的"回滾完成"訊息後,取消事務。
有時候,第二階段也被稱作 完成階段,因為無論結果怎樣,協調者都必須在此階段結束當前事務。
算法示意
下述流程圖(圖一)簡單示意了二階段提交算法中協調者和參與者之間的通信流程:
"*" 所標記的操作意味著此類操作必須記錄在穩固存儲上。
缺點
二階段提交算法的最大缺點就在於 它的執行過程中間,節點都處於阻塞狀態。即節點之間在等待對方的相應訊息時,它將什麼也做不了。特別是,當一個節點在已經占有了某項資源的情況下,為了等待其他節點的回響訊息而陷入阻塞狀態時,當第三個節點嘗試訪問該節點占有的資源時,這個節點也將連帶陷入阻塞狀態。
另外,協調者節點指示參與者節點進行提交等操作時,如有參與者節點出現了崩潰等情況而導致協調者始終無法獲取所有參與者的回響信息,這時協調者將只能依賴協調者自身的逾時機制來生效。但往往逾時機制生效時,協調者都會指示參與者進行回滾操作。這樣的策略顯得比較保守。