分佈式事務瞭解嗎?大家是如何解決分佈式事務問題的?面試
只要聊到你作了分佈式系統,必問分佈式事務,你對分佈式事務一無所知的話,確實會很坑,你起碼得知道有哪些方案,通常怎麼來作,每一個方案的優缺點是什麼。數據庫
如今面試,分佈式系統成了標配,而分佈式系統帶來的分佈式事務也成了標配了。由於你作系統確定要用事務吧,若是是分佈式系統,確定要用分佈式事務吧。先不說你搞過沒有,起碼你得明白有哪幾種方案,每種方案可能有啥坑?好比 TCC 方案的網絡問題、XA 方案的一致性問題。網絡
分佈式事務的實現主要有如下 5 種方案:架構
所謂的 XA 方案,即:兩階段提交,有一個事務管理器的概念,負責協調多個數據庫(資源管理器)的事務,事務管理器先問問各個數據庫你準備好了嗎?若是每一個數據庫都回復 ok,那麼就正式提交事務,在各個數據庫上執行操做;若是任何其中一個數據庫回答不 ok,那麼就回滾事務。併發
這種分佈式事務方案,比較適合單塊應用裏,跨多個庫的分佈式事務,並且由於嚴重依賴於數據庫層面來搞定複雜的事務,效率很低,絕對不適合高併發的場景。若是要玩兒,那麼基於 Spring + JTA
就能夠搞定,本身隨便搜個 demo 看看就知道了。分佈式
這個方案,咱們不多用,通常來講某個系統內部若是出現跨多個庫的這麼一個操做,是不合規的。我能夠給你們介紹一下, 如今微服務,一個大的系統分紅幾十個甚至幾百個服務。通常來講,咱們的規定和規範,是要求每一個服務只能操做本身對應的一個數據庫。微服務
若是你要操道別的服務對應的庫,不容許直連別的服務的庫,違反微服務架構的規範,你隨便交叉胡亂訪問,幾百個服務的話,全體亂套,這樣的一套服務是無法管理的,無法治理的,可能會出現數據被別人改錯,本身的庫被別人寫掛等狀況。高併發
若是你要操道別人的服務的庫,你必須是經過調用別的服務的接口來實現,絕對不容許交叉訪問別人的數據庫。code
TCC 的全稱是:Try、Confirm、Cancel。cdn
這種方案說實話幾乎不多人使用,咱們用的也比較少,可是也有使用的場景。由於這個事務回滾其實是嚴重依賴於你本身寫代碼來回滾和補償了,會形成補償代碼巨大,很是之噁心。
好比說咱們,通常來講跟錢相關的,跟錢打交道的,支付、交易相關的場景,咱們會用 TCC,嚴格保證分佈式事務要麼所有成功,要麼所有自動回滾,嚴格保證資金的正確性,保證在資金上不會出現問題。
並且最好是你的各個業務執行的時間都比較短。
可是說實話,通常儘可能別這麼搞,本身手寫回滾邏輯,或者是補償邏輯,實在太噁心了,那個業務代碼很難維護。
本地消息表實際上是國外的 ebay 搞出來的這麼一套思想。
這個大概意思是這樣的:
這個方案說實話最大的問題就在於嚴重依賴於數據庫的消息表來管理事務啥的,會致使若是是高併發場景咋辦呢?咋擴展呢?因此通常確實不多用。
這個的意思,就是乾脆不要用本地的消息表了,直接基於 MQ 來實現事務。好比阿里的 RocketMQ 就支持消息事務。
大概的意思就是:
這個方案的大體意思就是:
若是你真的被問到,能夠這麼說,咱們某某特別嚴格的場景,用的是 TCC 來保證強一致性;而後其餘的一些場景基於阿里的 RocketMQ 來實現分佈式事務。
你找一個嚴格資金要求絕對不能錯的場景,你能夠說你是用的 TCC 方案;若是是通常的分佈式事務場景,訂單插入以後要調用庫存服務更新庫存,庫存數據沒有資金那麼的敏感,能夠用可靠消息最終一致性方案。
友情提示一下,RocketMQ 3.2.6 以前的版本,是能夠按照上面的思路來的,可是以後接口作了一些改變,我這裏再也不贅述了。
固然若是你願意,你能夠參考可靠消息最終一致性方案來本身實現一套分佈式事務,好比基於 RocketMQ 來玩兒。