本分佈式事務系列主要講分佈式事務從
理論-> 解決方案 -> 使用框架 -> 實現及原理 -> 案例實戰 -> 事務回滾(全局異常統一處理)->分佈式事務消息
該篇着重於講述分佈式事務的解決方案,與各位一起打開新視界的大門。
1.柔性事務與剛性事務
2.傳統分佈式事務解決方案Jta+Atomikos
3.提交協議2PC與3PC
4.分佈式事務解決方案
一、柔性事務與剛性事務
話不多說上理論......
柔性事務滿足BASE理論(基本可用,最終一致)
剛性事務滿足ACID理論
我們主要圍繞分佈式事務當中的柔性事務的處理方式進行討論。
柔性事務分爲
1. 兩階段型 2PC 階段提交(A提交成功 -> B提交成功。AB相互關聯,但AB互不影響)
2. 補償型 --消息中間件(A提交->B提交失敗。中間件補償B,補償隊列,死信隊列,後期有案例)
3. 異步確保型 --同步操作,異步確保 (異步與同步.....支付案例了,篇一提到過)
4. 最大努力通知型。
篇一案例中,由於支付寶整個架構是SOA架構,因此傳統單機環境下數據庫的ACID事務滿足了分佈式環境下的業務需要,以上幾種事務類似就是針對分佈式環境下業務需要設定的。故這裏不進行ACID討論。
二、傳統分佈式事務解決方案Jta+Atomikos
這裏就是傳統項目,使用多數據源,即多個數據庫了。所以大多數採用Jta + Atomikos進行解決分佈式事務問題。
該框架底層是基於XA協議的兩階段提交方案。
名詞含義簡介:
XA協議:XA 事務的基礎是兩階段提交協議。需要有一個事務協調者來保證所有的事務參與者都完成了準備工作(第一階段)。如果協調者收到所有參與者都準備好的消息,就會通知所有的事務都可以提交了(第二階段)。Mysql 在這個XA事務中扮演的是參與者的角色,而不是協調者(事務管理器)。
JTA:JTA(java Transaction API)是JavaEE 13 個開發規範之一。java 事務API,允許應用程序執行分佈式事務處理——在兩個或多個網絡計算機資源上訪問並且更新數據。JDBC驅動程序的JTA支持極大地增強了數據訪問能力。事務最簡單最直接的目的就是保證數據的有效性,數據的一致性
Atomikos:Atomikos TransactionsEssentials 是一個爲Java平臺提供增值服務的並且開源類事務管理器
Jta + Atomikos只適合在傳統項目多數據源情況下使用,底層實現則是2PC(提交協議)
解決原理:
傳統項目中唯一可能產生的也就是多數據源,那麼多數據源有他獨立的事務管理器,所以就會產生事務獨立,從而達不到單個方法回滾多個事務。所以產生分佈式事務問題,那麼jta實現就是將多個事務,整合在一起,通過Jta來進行事務管理,也就是二階段提交協議。達到回滾多個事務,從而解決分佈式事務問題。
三、提交協議2PC與3PC
3.1、2PC
第一階段:準備階段:
協調者向參與者發起指令,參與者評估自己的狀態,如果參與者評估指令可以完成,則會寫redo或者undo日誌,然後鎖定資源,執行操作,但並不提交。
這裏可以理解爲,小明約小剛與小紅這週六去吃飯聚一聚,先通知兩位,小剛與小紅各自確認自己週六是否能夠參與,如果可以參與,就會回覆小明各自能去。
等等...你可能會想叫小紅一個妹子不就可以了麼? 答: .......
第二階段: 提交階段:
如果每個參與者明確返回準備成功,則協調者向參與者發送提交指令,參與者釋放鎖定的資源,如果任何一個參與者明確返回準備失敗,則協調者會發送中指指令,參與者取消已經變更的事務,釋放鎖定的資源。
這裏可以理解爲,小剛與小紅如果都能參與這次聚餐,那麼小明就認爲達到了條件,然後分享餐廳地址給兩位參與人,兩位參與人得到消息後趕到餐廳完成任務。如果有一方不去,那麼取消本次聚餐。
兩階段提交方案應用非常廣泛,幾乎所有商業OLTP數據庫都支持XA協議。但是兩階段提交方案鎖定資源時間長,對性能影響很大,基本不適合解決微服務事務問題。
缺點:如果協調者宕機,參與者沒有協調者指揮,則會一直阻塞。
如果小明說了週六去聚餐,小剛與小紅都同意了,但小明一直不回消息,這裏就會造成阻塞。讓小剛小紅到了週六也一直在等小明回覆餐廳在哪兒。結果被放了鴿子,消耗了時間資源。
等等....你可能會說然後小剛就不能私自和小紅去吃了?答: .......
3.2、3PC
第一階段是表決階段(詢問階段),所有參與者都將本事務能否成功的信息反饋發給協調者;
第二階段是執行階段(準備階段),協調者根據所有參與者的反饋,通知所有參與者,步調一致地在所有分支上提交或者回滾。
第三階段提交協議是兩階段提交協議的改進版本。它通過超時機制解決了阻塞的問題,並且把兩個階段增加爲三個階段:
- 詢問階段:
協調者詢問參與者是否可以完成指令,參與者只需要回答是還是不是,而不需要做真正的操作,這個階段超時導致中止。
- 準備階段:
如果在詢問階段所有的參與者都返回可以執行操作,協調者向參與者發送預執行請求,然後參與者寫redo和undo日誌,執行操作,但是不提交操作;如果在詢問階段任何參與者返回不能執行操作的結果,則協調者向參與者發送中止請求,這裏的邏輯與兩階段提交協議的的準備階段是相似的,這個階段超時導致操作不成功。
- 提交階段:
如果每個參與者在準備階段返回準備成功,也就是預留資源和執行操作成功,協調者向參與者發起提交指令,參與者提交資源變更的事務,釋放鎖定的資源;如果任何一個參與者返回準備失敗,也就是預留資源或者執行操作失敗,協調者向參與者發起中止指令,參與者取消已經變更的事務,執行undo日誌,釋放鎖定的資源,這裏的邏輯與兩階段提交協議的提交階段一致
3.3、2PC與3PC的區別:
3PC增加了詢問機制與超時機制。
增加了一個詢問階段,詢問階段可以確保儘可能早的發現無法執行操作而需要中止的行爲,但是它並不能發現所有的這種行爲,只會減少這種情況的發生在準備階段以後,協調者和參與者執行的任務中都增加了超時,一旦超時,協調者和參與者都繼續提交事務,默認爲成功,這也是根據概率統計上超時後默認成功的正確性最大、
三階段提交協議與兩階段提交協議相比,具有如上的優點,但是一旦發生超時,系統仍然會發生不一致,只不過這種情況很少見罷了,好處就是至少不會阻塞和永遠鎖定資源。
四、分佈式事務解決方案
常見解決方案:
分佈式事務常見解決方案
- 傳統模式使用Jta+Atomikos
- 2PC與3PC實現的區別
- 使用TCC補償框架 (Easy Transaction)
- 使用可靠消息模式(中間件) 或 同步異步確保 最終一致性(消息補償)
- 使用LCN框架解決分佈式事務(重點) 第三方 類3PC模式
- 阿里GTS框架解決分佈式事務 Seata
- 支付案例消息通知 (跨平臺 SOA)
後文主要講
LCN框架解決分佈式事務、消息中間件解決分佈式事務與併發優化設計、阿里Seata解決分佈式事務