前言
最近業(yè)務(wù)變動準(zhǔn)備面試,看了一下別人的面試情況板惑,都問了關(guān)于分布式事務(wù)的問題龙致。所以今天整理一下绩脆。
分布式事務(wù)解決方案
1. XA 方案(兩階段提交方案)
- 支持的場景:一個(gè)服務(wù)操作多個(gè)數(shù)據(jù)庫掰茶,要求事務(wù)跨數(shù)據(jù)庫保持一致性
- 實(shí)現(xiàn)原理:事務(wù)管理器(服務(wù)器)對多個(gè)資源管理器(數(shù)據(jù)庫)發(fā)起事務(wù)暇藏,多個(gè)資源管理器完成事務(wù)任務(wù)后先不進(jìn)行 commit 操作,事務(wù)管理器檢查所有資源管理器上的事務(wù)是否都能夠完成并都處于待提交狀態(tài)濒蒋。如果有至少一個(gè)文件管理器無法完成被分配的事務(wù)任務(wù)叨咖,則事務(wù)管理器通知全部文件管理器進(jìn)行回滾。如果全部文件管理器都進(jìn)入了待提交狀態(tài)啊胶,則事務(wù)管理器發(fā)起提交請求甸各,讓資源管理器提交各自的事務(wù)。
- 優(yōu)點(diǎn):通過事務(wù)管理器本身支持的事務(wù)性操作來實(shí)現(xiàn)回滾操作焰坪,業(yè)務(wù)側(cè)實(shí)現(xiàn)比較簡單趣倾。
- 缺點(diǎn):一個(gè)服務(wù)操作多個(gè)數(shù)據(jù)庫的場景,現(xiàn)在幾乎不存在∧呈危現(xiàn)在的服務(wù)基本都是微服務(wù)的形式儒恋,每個(gè)服務(wù)只有自己的一個(gè)數(shù)據(jù)庫或者沒有數(shù)據(jù)庫。如果一個(gè)服務(wù)操作多個(gè)數(shù)據(jù)庫黔漂,那么除了操作自己的數(shù)據(jù)庫還要操作別人的數(shù)據(jù)庫诫尽,那就亂套了。別人的數(shù)據(jù)庫是不可能讓你操作的炬守。
2. TCC 方案(Try - Confirm / Cancel)
- 支持的場景:TCC 方案可以支持強(qiáng)一致性的分布式事務(wù)牧嫉,適合于銀行轉(zhuǎn)賬等要求強(qiáng)一致性的場景
- 實(shí)現(xiàn)原理:事務(wù)分為三個(gè)階段,即 T - C - C减途。首先是 Try 階段通知所有參與的服務(wù)器檢查資源并且鎖定資源酣藻,如果全部服務(wù)器都可以正常執(zhí)行 try,則執(zhí)行 confirm 操作鳍置,即讓參與的服務(wù)器執(zhí)行各自的操作辽剧,如果有一個(gè)服務(wù)器無法滿足 try 執(zhí)行的條件,則向其他服務(wù)器發(fā)送 cancel 命令税产,撤回對資源的鎖定怕轿。
- 示例:銀行賬戶 A 轉(zhuǎn)賬 100 元到賬戶 B,且這兩個(gè)賬戶分別隸屬于服務(wù)器①和服務(wù)器②辟拷,事務(wù)發(fā)起的服務(wù)器記作服務(wù)器③撞羽。try 階段:服務(wù)器③向服務(wù)器①②發(fā)送 try 指令,服務(wù)器①鎖定 A 賬戶并檢查 A 賬戶余額是否大于等于 100梧兼,服務(wù)器②鎖定 B 賬戶放吩。confirm 階段:如果 try 階段無異常智听,則服務(wù)器③向服務(wù)器①②發(fā)送 confirm 指令羽杰,服務(wù)器①將 A 賬戶余額減去 100 并保存渡紫,服務(wù)器②向 B 賬戶增加 100。 如果 try階段不能正確執(zhí)行考赛,比如 A 賬戶余額只有 90 了惕澎,則執(zhí)行 cancel 命令,釋放鎖定的 AB 賬戶颜骤。
- 優(yōu)點(diǎn):強(qiáng)一致性唧喉,確保完全的事務(wù)完整性
- 缺點(diǎn):所有事務(wù)操作代碼,例如回滾忍抽,都需要業(yè)務(wù)側(cè)自行編寫八孝,極大增加了開發(fā)難度。另外鸠项,由于網(wǎng)絡(luò)問題干跛,try-confirm-cancel 信號可能受到影響,會出現(xiàn)諸多問題祟绊,例如楼入,沒有收到 try 就收到了 cancel 那么服務(wù)器必須支持空回滾,或者收到了兩次 confirm牧抽,則要求服務(wù)器支持冪等操作嘉熊。
3. 可靠消息最終一致性方案
- 支持場景:沒有強(qiáng)一致性要求,只要求最終一致性的場景扬舒,例如賬單支付和商品發(fā)貨阐肤,賬單支付后,無需同時(shí)進(jìn)行商品發(fā)貨只要最終商品可以發(fā)貨就行
- 實(shí)現(xiàn)原理: 例如服務(wù)器A 支持賬單支付讲坎,服務(wù)器 B 支持商品發(fā)貨泽腮,服務(wù)器 A 在執(zhí)行賬單支付之前發(fā)送一條 prepare 到消息隊(duì)列,如果發(fā)送失敗衣赶,則服務(wù)器 A 立即取消后續(xù)操作诊赊,如果發(fā)送成功,則服務(wù)器 A 繼續(xù)支付操作府瞄,支付成功則發(fā)送成功消息給消息隊(duì)列碧磅,支付失敗則發(fā)送失敗消息給消息隊(duì)列。如果是成功的消息遵馆,則服務(wù)器 B 馬上執(zhí)行發(fā)貨操作鲸郊,如果失敗則一直重試,直到成功或者超時(shí)货邓。如果 B 超時(shí)未完成秆撮,則想辦法通知 A 回滾,或者發(fā)送報(bào)警消息進(jìn)行人工回滾换况。
- 優(yōu)點(diǎn):簡單高效易于實(shí)現(xiàn)职辨,能夠?qū)崿F(xiàn)最終一致性
- 缺點(diǎn):無法實(shí)現(xiàn)強(qiáng)一致性