在微服務的系統(tǒng)中,各個微服務的數(shù)據(jù)庫都是分開的,所以事務不能交給MySQL去管理了,必須通過一些別的方式去完成。
2PC
2PC 是基于 XA 規(guī)范搞出來的一套分布式事務的理論,全稱是 Two-Phase-Commitment-Protocol,兩階段提交協(xié)議。
先說下 XA 規(guī)范:
XA規(guī)范
有個叫 X/Open 的組織定義了分布式事務的模型,里面有如下角色:
- AP:Application 應用程序 -> 整個系統(tǒng)
- TM:Transaction Manager,事務管理器 -> 管理事務的組件
- RM:Resource Manager,資源管理器 -> MySQL
- CRM:Communication Resource Manager,通信資源管理器 -> 消息中間件
XA其實就是定義了TM個RM之間的接口規(guī)范,為了方便數(shù)據(jù)庫一起回滾,MySQL也有實現(xiàn),但實際中不好用
繼續(xù)說回2PC
簡單說
2PC 的第一階段就是讓各個數(shù)據(jù)庫都先執(zhí)行SQL,但不提交,等所有都正常執(zhí)行,一起提交,或者異常之后一起回滾。
流程
按照1.1->1.2->1.3->2.1->2.2->2.3 的順序執(zhí)行

如果1.2或者1.3執(zhí)行失敗,那么正在執(zhí)行的和執(zhí)行過的都會回滾
問題
這樣好像是解決了分布式事務的問題,但還是有一些問題。
- 同步阻塞:數(shù)據(jù)庫1需要等待整個事務執(zhí)行完成才能繼續(xù)
- 單點故障:TM是單點故障,掛了就結束了,如果做雙擊熱備,備份TM不知道哪些提交了或者執(zhí)行了
- 腦裂問題:如果因為網(wǎng)絡問題,有些收到了commit,有些沒收到,數(shù)據(jù)就會有問題了
為了解決上面出現(xiàn)的一些問題,其實主要是怕其中一些數(shù)據(jù)庫掛了,或者因為網(wǎng)絡問題導致沒有成功,所以出現(xiàn)了3PC
3PC
全稱是 Three-Phase-Commitment-Protocol,三階段提交協(xié)議,其實主要解決第三個腦裂問題。
簡單說就是比2PC多了一個check的步驟

- 第一階段提交 canCommit,檢查下數(shù)據(jù)庫是不是都有問題
- 第二階段開始執(zhí)行,但不提交,和2PC的第一階段一樣
- 第二階段都執(zhí)行成功了,第三階段就開始執(zhí)行提交
如果這時候的commit 請求因為網(wǎng)絡問題沒有送達,或者二階段數(shù)據(jù)庫發(fā)給TM的執(zhí)行成功的消息沒有送達,因為一階段已經(jīng)確定數(shù)據(jù)庫是正常的,所以這里收到通知很大程度的原因是網(wǎng)絡故障,所以3PC引入了超時機制。
超時機制
如果數(shù)據(jù)庫二階段結束后過了一段時間沒有收到 commit 消息,那么數(shù)據(jù)庫就默認 TM 掛了,自己執(zhí)行 commit。這樣的話,就解決了如下問題:
- 不會因為事務一直占用資源;
- 對于單次事務,也不會擔心TM掛了;
- 腦裂問題也解決了,沒收到commit的數(shù)據(jù)庫也會在超時時間到達后自動commit
問題
但其實還有問題,可能一階段數(shù)據(jù)庫是好的,后面掛了,TM并不知道,以為整個事務執(zhí)行成功了?;蛘吆竺嬗袛?shù)據(jù)庫異常了,應該要回滾,但是異常沒有通知到TM,或者TM掛了,別的數(shù)據(jù)庫也會commit,數(shù)據(jù)就會有問題。只能說3PC解決了大部分問題,是一個較優(yōu)的方案。