分布式事務解決方案

2021-07-30 12:06:02 字數 3098 閱讀 1012

當資料庫單錶一年產生的資料超過1000w,那麼就要考慮分庫分表,具體分庫分表的原理在此不做解釋,以後有空詳細說,簡單的說就是原來的乙個資料庫變成了多個資料庫。這時候,如果乙個操作既訪問01庫,又訪問02庫,而且要保證資料的一致性,那麼就要用到分布式事務。

所謂的soa化,就是業務的服務化。比如原來單機支撐了整個電商**,現在對整個**進行拆解,分離出了訂單中心、使用者中心、庫存中心。對於訂單中心,有專門的資料庫儲存訂單資訊,使用者中心也有專門的資料庫儲存使用者資訊,庫存中心也會有專門的資料庫儲存庫存資訊。這時候如果要同時對訂單和庫存進行操作,那麼就會涉及到訂單資料庫和庫存資料庫,為了保證資料一致性,就需要用到分布式事務。

以上兩種情況表象不同,但是本質相同,都是因為要操作的資料庫變多了!

所謂的原子性就是說,在整個事務中的所有操作,要麼全部完成,要麼全部不做,沒有中間狀態。對於事務在執行中發生錯誤,所有的操作都會被回滾,整個事務就像從沒被執行過一樣。

事務的執行必須保證系統的一致性,就拿轉賬為例,a有500元,b有300元,如果在乙個事務裡a成功轉給b50元,那麼不管併發多少,不管發生什麼,只要事務執行成功了,那麼最後a賬戶一定是450元,b賬戶一定是350元。

所謂的隔離性就是說,事務與事務之間不會互相影響,乙個事務的中間狀態不會被其他事務感知。

所謂的永續性,就是說一單事務完成了,那麼事務對資料所做的變更就完全儲存在了資料庫中,即使發生停電,系統宕機也是如此。

最經典的場景就是支付了,一筆支付,是對買家賬戶進行扣款,同時對賣家賬戶進行加錢,這些操作必須在乙個事務裡執行,要麼全部成功,要麼全部失敗。而對於買家賬戶屬於買家中心,對應的是買家資料庫,而賣家賬戶屬於賣家中心,對應的是賣家資料庫,對不同資料庫的操作必然需要引入分布式事務。

買家在電商平台下單,往往會涉及到兩個動作,乙個是扣庫存,第二個是更新訂單狀態,庫存和訂單一般屬於不同的資料庫,需要使用分布式事務保證資料一致性。

xa是乙個分布式事務協議,由tuxedo提出。xa中大致分為兩部分:事務管理器和本地資源管理器。其中本地資源管理器往往由資料庫實現,比如oracle、db2這些商業資料庫都實現了xa介面,而事務管理器作為全域性的排程者,負責各個本地資源的提交和回滾。xa實現分布式事務的原理如下:

總的來說,xa協議比較簡單,而且一旦商業資料庫實現了xa協議,使用分布式事務的成本也比較低。但是,xa也有致命的缺點,那就是效能不理想,特別是在交易下單鏈路,往往併發量很高,xa無法滿足高併發場景。xa目前在商業資料庫支援的比較理想,在mysql資料庫中支援的不太理想,mysql的xa實現,沒有記錄prepare階段日誌,主備切換回導致主庫與備庫資料不一致。許多nosql也沒有支援xa,這讓xa的應用場景變得非常狹隘。

所謂的訊息事務就是基於訊息中介軟體的兩階段提交,本質上是對訊息中介軟體的一種特殊利用,它是將本地事務和發訊息放在了乙個分布式事務裡,保證要麼本地操作成功成功並且對外發訊息成功,要麼兩者都失敗,開源的rocketmq就支援這一特性。

具體的關於一些事務訊息的東西,我這邊也提供了2偏自己認為比較好的文章

事務訊息缺點:

事務訊息也有自己的瓶頸,使用事務訊息前提是服務之間沒有相互依賴性。下面的需求就不適用用事務訊息:電商一筆訂單完成,並扣除該使用者的現金餘額。訂單的完成是依賴現金餘額的,總不能都沒有現金或者現金不夠就訂單完成v吧。像這種場景,事務訊息就不適用了,訂單事務和現金事務幾乎要一起提交、回滾的,並不是訂單事務先提交後去保證現金事務提交

上面的事務訊息是解決分布式事務的乙個方案,但事務訊息也有自己但乙個瓶頸,就是要使用事務訊息,必須保證服務a,和服務b在業務上沒有相互依賴d

tcc的核心思想:

1,try階段是為confim階段提前做乙個預執行(**試),提前鎖定一些資源,提前測試一些環境是否正常,比如資料庫,redis之類的中介軟體是否正常

2,各個try階段都成功之後,才執行相應的confirm階段,當try階段完成時,我們認為confirm會大概率完成

3,try階段失敗時,cancel階段會返回try階段執行之前的狀態

上面就是對於tcc模式的乙個概括性的總結,但很多細節性但東西都是空的,比如下面的一些問題

tcc模式的問題:

1,怎麼知道哪些try階段成功哪些失敗了?,如果都成功了,如何通知可以執行confirm階段了

2,如果大概率成功的confirm階段,cancel階段執行失敗了怎麼辦?

3,如果在try階段,cancel階段,機器突然掛了怎麼辦?

上面的一些問題就是要乙個個去解決,不過現在國內的一些tcc框架(bytetcc,tcc-transaction,himly。)已經有成熟的了,不用自己花大量的時間去做乙個tcc框架。

針對的上面的問題,一些框架的做法:

1,tcc框架會利用相關的通訊技術,獲取各個階段的狀態,通知各個階段可以執行,或者不能執行

2,tcc框架會利用日誌記錄各個分布式事務相關操作狀態,當cancel,confirm階段失敗時首先會進行重試(所以這裡要做好冪等),如果真的一直沒有成功,一般會進行事務補償

3,第二條也說了框架會把活動的日誌以檔案的形式,或者資料庫的形式儲存,具體看框架的時候,這樣即使失敗了,當重啟的時候又會繼續掛機之前的流程

附上好文章的位址

6、總結

分布式事務,本質上是對多個資料庫的事務進行統一控制,按照控制力度可以分為:不控制、部分控制和完全控制。不控制就是不引入分布式事務,部分控制就是各種變種的兩階段提交,包括上面提到的訊息事務+最終一致性、tcc模式,而完全控制就是完全實現兩階段提交。部分控制的好處是併發量和效能很好,缺點是資料一致性減弱了,完全控制則是犧牲了效能,保障了一致性,具體用哪種方式,最終還是取決於業務場景。作為技術人員,一定不能忘了技術是為業務服務的,不要為了技術而技術,針對不同業務進行技術選型也是一種很重要的能力!

本人:分布式事物,無非就是增加一層中介軟體,我忘記在**看到的一句話,無論什麼問題都是通過增加一層中介軟體解決的。分布式事物也就是在原先的事物上增加一層控制器,保持兩個基本的事物保持一致。換句話就是分布式事物=基礎事物+中介軟體(jms,管理層。。。。。)

事務 分布式事務解決方案

事務acid特性 事務隔離級別 指的是讀和寫同時出現時出現的資料不一致問題。事務的一致性問題 存在問題問題描述 髒讀 dirty read 針對的是單條資料。即乙個更新操作a修改了某一條資料,但尚未提交該事務,此時另乙個讀操作b來查詢該條資料,讀到的是修改後的但尚未提交的資料。不可重複讀 unrep...

分布式事務解決方案

一 結合mq訊息中介軟體實現的可靠訊息最終一致性 二 tcc補償性事務解決 三 最大努力通知型方案 第一種方案 可靠訊息最終一致性,需要業務系統結合mq訊息中介軟體實現,在實現過程中需要保證訊息的成功傳送及成功消費。即需要通過業務系統控制mq的訊息狀態 第二種方案 tcc補償性,分為三個階段tryi...

分布式事務解決方案

由於資料量的巨大,大部分web應用都需要部署很多個資料庫例項。這樣,有些使用者操作就可能需要去修改多個資料庫例項中的資料。傳統的解決方法是使用分布式事務保證資料的全域性一致性,經典的方法是使用兩階段提交協議。長期以來,分布式事務提供的優雅的全域性acid保證麻醉了應用開發者的心靈,很多人都不敢越雷池...