這篇說說分佈式事務的問題。企業如今的架構都由傳統的架構轉向了微服務架構,以下圖所示:
那麼,都不可避免的會遇到跨數據庫調用的,分佈式事務問題!
目前,業內解決分佈式事務問題,都基本不用JTA這種強一致性的解決方案,基本是採用以下兩套方案html
OK,大家先記住兩點
(1)圖中的服務A和服務B,若是是同步調用,要求一塊兒成功,或者一塊兒失敗,那麼此時應選用TCC的事務框架,這點我改天另寫一篇,先挖坑!
(2)圖中的服務A和服務B,若是是異步調用,好比服務C先調用服務A後,服務C不用管服務B的執行結果,直接返回,那麼這種狀況下,應選用消息隊列!這篇文章重點講!
目前爲止,大部分文章都講的太複雜了。致使不少新人看完後因而看這篇文章前,大家先忘記大家在其餘文章看到的概念,跟着博主的思路走!面試
先給你們套一個業務場景,也是很常見的一個異步調用場景:數據庫
即將服務A假設爲支付寶,服務B假設爲餘額寶。
因而呢,咱們的支付寶往餘額寶轉100塊錢是怎麼作的呢?
特別容易,藉助消息隊列便可,以下圖所示
緩存
OK,上面這一版有一個致命的問題!以下所示
事務開始
(1)給支付寶帳戶zhangsan,扣100元
(2)將(給餘額寶帳戶zhangsan,加100元)封裝爲消息,發送給消息隊列
事務結束
敢問你,如何保證第一步和第二步是在同一個事務裏完成的。換句話說,第一步操做的是數據庫,第二步操做的是一個消息隊列,你如何保證這兩步之間的一致性?
記住了,任何涉及到數據庫和中間件之間的業務邏輯操做,都須要考慮兩者之間的一致性。好比,你先操做了數據庫,再操做緩存,數據庫和緩存之間一致性如何解決?好吧,若是是博主的鐵粉,應該知道怎麼解決了,回到咱們的場景。
改變思路,加一張事務表,以下圖所示
架構
注意了,此時事務的內容爲
事務開始
(1)給支付寶帳戶zhangsan,扣100元
(2)給事件表插入一條記錄
事務結束
此時是對同一數據庫的兩張表操做,所以能夠用數據庫的事務進行保證。
另外,起一個定時程序,定時掃描事務表,發現一個狀態爲'UNFINISHED'的事件,就進行封裝爲消息,發送到消息中間件,而後將狀態改成'FINISHED'.框架
注意了,這一版還存在一個冪等性問題!
仔細看,定時程序作了以下三個操做
(1)定時掃描事務表,發現一個狀態爲'UNFINISHED'的事件
(2)將事件信息,封裝爲消息,發送到消息中間件
(3)將事件狀態改成'FINISHED'異步
OK,假設在步驟(2)的時候,發送完消息體,還未執行步驟(3),定時程序陣亡了!而後重啓定時程序,發現剛那個事務的狀態依然爲'UNFINISHED',所以從新發送。這樣,就會出現重複消費問題。所以,冪等性也是須要保證的!分佈式
若是是博主的忠實讀者,應該知道,博主曾經寫過一篇《分佈式之消息隊列複習精講》,裏頭就提到了如何解決冪等性問題。什麼?你沒看過這篇?拉出去槍斃!
借用這篇文章裏的方案。在消費者端,也維護一個帶主鍵的表,能夠選txid爲主鍵,以下圖所示
微服務
若是一旦出現重複消費,則在事務裏直接報出主鍵衝突錯誤,從而保證了冪等性!3d
面試官:"大家用了微服務架構麼?"
求職者:"用了,用了"
面試官:"怎麼解決分佈式事務的啊?"
求職者:"咱們的服務恰好是異步的場景,因此用消息隊列!"
面試官:"怎麼保證一致性和冪等性啊?"
求職者:"嗯,聽我細細說來....."
這篇文章說了微服務架構下,異步服務之間的分佈式事務是如何保證的。至於同步服務,博主儘可能抓緊寫!