問題
場景:訂單系統(tǒng)創(chuàng)建訂單成功,需購物車系統(tǒng)清空購物車中的訂單
業(yè)務(wù)執(zhí)行步驟:
- 在訂單庫中插入一條訂單數(shù)據(jù)瞬捕,創(chuàng)建訂單学搜;
- 發(fā)消息給消息隊列,消息的內(nèi)容就是剛剛創(chuàng)建的訂單多柑;
在分布式系統(tǒng)中上述兩個步驟都有可能失敗:
- 創(chuàng)建了訂單楣责,沒有清理購物車竣灌;
- 訂單沒創(chuàng)建成功,購物車里面的商品卻被清掉了秆麸;
需要解決的問題:上述任意步驟都有可能失敗的情況下初嘹,還要保證訂單庫和購物車庫這兩個庫的數(shù)據(jù)一致性。
對于購物車系統(tǒng)收到消息清理購物車處理比較簡單沮趣,只有成功刪除購物車才提交消息確認屯烦,否則重試
關(guān)鍵是在訂單系統(tǒng)中的 創(chuàng)建訂單和發(fā)送消息的兩個步驟如何確保同時成功或失敗
什么是事務(wù)
嚴格意義上的事務(wù)具有4個屬性:原子性、一致性房铭、隔離性驻龟、持久性
- 原子性:操作不能再分割,要么成功要么失敗缸匪,不能一半成功一半失敗
- 一致性:是指這些數(shù)據(jù)在事務(wù)執(zhí)行完成這個時間點之前翁狐,讀到的一定是更新前的數(shù)據(jù),之后讀到的一定是更新后的數(shù)據(jù)凌蔬,不應(yīng)該存在一個時刻露懒,讓用戶讀到更新過程中的數(shù)據(jù)闯冷。
- 隔離性:是指一個事務(wù)的執(zhí)行不能被其他事務(wù)干擾。即一個事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對正在進行的其他事務(wù)是隔離的懈词,并發(fā)執(zhí)行的各個事務(wù)之間不能互相干擾蛇耀。
- 持久性:是指一個事務(wù)一旦完成提交,后續(xù)的其他操作和故障都不會對事務(wù)的結(jié)果產(chǎn)生任何影響坎弯。
分布式事務(wù)
是在分布式系統(tǒng)中實現(xiàn)事務(wù)纺涤,在分布式事務(wù)中嚴格按事務(wù)的標準來要求是不可能實現(xiàn)的,光要實現(xiàn)數(shù)據(jù)的一致性就非常困難荞怒,最終只能保證順序的一致性洒琢、以及最終一致性
常見的分布式實現(xiàn)方式
- 2PC(Two-phase Commit,也叫二階段提交)
- TCC(Try-Confirm-Cancel)
- 事務(wù)消息
每一種實現(xiàn)都有其特定的使用場景褐桌,也有各自的問題衰抑,都不是完美的解決方案
2pc和tcc這里不做討論,主要來看下事務(wù)消息
消息隊列如何實現(xiàn)事務(wù)
事務(wù)消息需要消息隊列提供相應(yīng)的功能才能實現(xiàn)荧嵌,rocketmq和kafka都提供了事務(wù)相關(guān)功能
回到訂單系統(tǒng)的例子看如何實現(xiàn):
步驟:
- 1呛踊、開啟一個消息事務(wù)
- 2、訂單系統(tǒng)給消息服務(wù)發(fā)送一個半消息
半消息的消息內(nèi)容是完整的只是在事務(wù)沒有提交之前消費者是不可見的
- 3啦撮、執(zhí)行本地事務(wù)創(chuàng)建訂單
- 4谭网、提交或回滾消息事務(wù)
如果創(chuàng)建訂單成功則提交消息事務(wù),消息會投遞到購物車系統(tǒng)赃春,創(chuàng)建失敗則回滾事務(wù)消息
問題:提交消息事務(wù)失敗怎么辦
kafka比較粗暴愉择,直接拋出異常讓用戶自己解決,我們可以在業(yè)務(wù)代碼中反復(fù)提交知道提交成功织中,或刪除原來創(chuàng)建成功的訂單進行補償锥涕;rocketmq提供了另外一種解決方式
rocketmq分布式事務(wù)實現(xiàn)
事務(wù)反查機制
rocketmq提供了事務(wù)反查的機制,如果因網(wǎng)絡(luò)或其他原因?qū)е聄ocketmq沒有收到訂單系統(tǒng)的事務(wù)的提交或者回滾狭吼,會定期取訂單系統(tǒng)反查這個消息事務(wù)對應(yīng)的本地事務(wù)的狀態(tài)层坠,從而來確定事務(wù)是提交還是回滾,為了支持反查刁笙,業(yè)務(wù)代碼需要實現(xiàn)一個反查本地事務(wù)狀態(tài)的接口
最后
kafka需要自己寫代碼來解決問題破花,rocketmq通過反查機制解決,并不代表rocketmq事務(wù)功能比kafka好疲吸,只能說在此例場景更適合座每,Kafka 對于事務(wù)的定義、實現(xiàn)和適用場景摘悴,和 RocketMQ 有比較大的差異尺栖,后面的課程中,我們會專門講到 Kafka 的事務(wù)的實現(xiàn)原理烦租。
內(nèi)容來源說明:文章中的部分內(nèi)容以及圖片來自《極客時間-消息隊列高手課》延赌,寫文章目的只是作為學(xué)習(xí)后的總結(jié)和整理