1. 程式人生 > >分散式事務的理解

分散式事務的理解

https://blog.csdn.net/persistencegoing/article/details/84376427

 

 

分散式事務

分散式事務就是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分別位於不同的分散式系統的不同節點之上。以上是百度百科的解釋,簡單的說,就是一次大的操作由不同的小操作組成,這些小的操作分佈在不同的伺服器上,且屬於不同的應用,分散式事務需要保證這些小操作要麼全部成功,要麼全部失敗。本質上來說,分散式事務就是為了保證不同資料庫的資料一致性。

分散式事務的產生的原因

  • 資料庫分庫分表
    • 如果一個操作既訪問01庫,又訪問02庫,而且要保證資料的一致性,那麼就要用到分散式事務。
  • 應用SOA化
    • 即業務的服務化。如單體應用電商網站,SOA拆解分離出了訂單中心、使用者中心、庫存中心等。各模組有專門的資料庫儲存資訊。 此時,如果要同時對訂單和庫存進行操作就會涉及到訂單資料庫和庫存資料庫,為了保證資料一致性,就需要用到分散式事務。

本質相同,都是因為一段邏輯需要操作的資料庫變多了。

 

分散式事務的應用場景

  • 支付
    • 最經典的場景就是支付了,一筆支付,是對買家賬戶進行扣款,同時對賣家賬戶進行加錢,這些操作必須在一個事務裡執行,要麼全部成功,要麼全部失敗。而對於買家賬戶屬於買家中心,對應的是買家資料庫,而賣家賬戶屬於賣家中心,對應的是賣家資料庫,對不同資料庫的操作必然需要引入分散式事務。
  • 線上下單
    • 買家在電商平臺下單,往往會涉及到兩個動作,一個是扣庫存,第二個是更新訂單狀態,庫存和訂單一般屬於不同的資料庫,需要使用分散式事務保證資料一致性。

常見的分散式事務解決方案

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

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

        1、A系統向訊息中介軟體傳送一條預備訊息
        2、訊息中介軟體儲存預備訊息並返回成功
        3、A執行本地事務
        4、A傳送提交訊息給訊息中介軟體
        通過以上4步完成了一個訊息事務。對於以上的4個步驟,每個步驟都可能產生錯誤,下面一一分析:
      
        步驟一出錯,則整個事務失敗,不會執行A的本地操作
        步驟二出錯,則整個事務失敗,不會執行A的本地操作
        步驟三出錯,這時候需要回滾預備訊息,怎麼回滾?答案是A系統實現一個訊息中介軟體的回撥介面,訊息中介軟體會去不斷執行回撥介面,檢查A事務執行是否執行成功,如果失敗則回滾預備訊息
        步驟四出錯,這時候A的本地事務是成功的,那麼訊息中介軟體要回滾A嗎?答案是不需要,其實通過回撥介面,訊息中介軟體能夠檢查到A執行成功了,這時候其實不需要A發提交訊息了,訊息中介軟體可以自己對訊息進行提交,從而完成整個訊息事務
        基於訊息中介軟體的兩階段提交往往用在高併發場景下,將一個分散式事務拆成一個訊息事務(A系統的本地操作+發訊息)+B系統的本地操作,其中B系統的操作由訊息驅動,只要訊息事務成功,那麼A操作一定成功,訊息也一定發出來了,這時候B會收到訊息去執行本地操作,如果本地操作失敗,訊息會重投,直到B操作成功,這樣就變相地實現了A與B的分散式事務。原理如下:
      
        1、訊息中介軟體獲取A的提交訊息。
        2、訊息中介軟體想B傳送訊息。
      
        雖然上面的方案能夠完成A和B的操作,但是A和B並不是嚴格一致的,而是最終一致的,我們在這裡犧牲了一致性,換來了效能的大幅度提升。當然,這種玩法也是有風險的,如果B一直執行不成功,那麼一致性會被破壞,具體要不要玩,還是得看業務能夠承擔多少風險。

TCC程式設計模式

所謂的TCC程式設計模式,也是兩階段提交的一個變種。TCC提供了一個程式設計框架,將整個業務邏輯分為三塊:Try、Confirm和Cancel三個操作。以線上下單為例,Try階段會去扣庫存,Confirm階段則是去更新訂單狀態,如果更新訂單失敗,則進入Cancel階段,會去恢復庫存。總之,TCC就是通過程式碼人為實現了兩階段提交,不同的業務場景所寫的程式碼都不一樣,複雜度也不一樣,因此,這種模式並不能很好地被複用。

總結

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

 

轉  載:http://www.xuxueli.com/blog/#/notebook/%E6%95%B0%E6%8D%AE%E5%BA%93/%E6%95%B0%E6%8D%AE%E5%BA%93%EF%BC%9A%E5%88%86%E5%B8%83%E5%BC%8F%E4%BA%8B%E5%8A%A1

 

希望大家關注我一波,防止以後迷路,有需要的可以加群討論互相學習java ,學習路線探討,經驗分享與java求職      群號:721515304