Seata解決方案整體介紹


1.SEATA是什么:

     Seata 是一款開源的分布式事務解決方案,致力於提供高性能和簡單易用的分布式事務服務。Seata 為用戶提供了 ATTCCSAGA XA 事務模式,為用戶打造一站式的分布式解決方案。

 

 

2、SEATA整體框架:

     Seata 中有三大模塊,分別是 TM、RM 和 TC。其中 TM 和 RM 是作為 Seata 的客戶端與業務系統集成在一起,TC 作為 Seata 的服務端獨立部署。

 

 

 

角色划分:

TM事務管理器,開啟、 提交、回滾分布式事務

RM: 資源管理器,注冊、 匯報、執⾏資源

TC :  事務管理器服務功能,存儲事務日志、補償異常事務等、集中管理事務全局鎖(全局行鎖),seata服務端

 

事務執行整體流程:

  • TM 開啟分布式事務(TM 向 TC 注冊全局事務記錄);
  • 按業務場景,編排數據庫、服務等事務內資源(RM 向 TC 匯報資源准備狀態 );
  • TM 結束分布式事務,事務一階段結束(TM 通知 TC 提交/回滾分布式事務);
  • TC 匯總事務信息,決定分布式事務是提交還是回滾;
  • TC 通知所有 RM 提交/回滾 資源,事務二階段結束;

3、AT模式介紹

AT 模式是一種無侵入的分布式事務解決方案。在 AT 模式下,用戶只需關注自己的“業務 SQL”,用戶的 “業務 SQL” 作為一階段,Seata 框架會自動生成事務的二階段提交和回滾操作。

1、 整體機制:

   兩階段提交協議的演變:

   一階段:業務數據和回滾日志記錄在同一個本地事務中提交,釋放本地鎖和連接資源。

   二階段:

    • 提交異步化,非常快速地完成。
    • 回滾通過一階段的回滾日志進行反向補償。

2、詳細流程:

一階段提交:

  在一階段,Seata 會攔截“業務 SQL”,首先解析 SQL 語義,找到“業務 SQL”要更新的業務數據,在業務數據被更新前,將其保存成“before image”,然后執行“業務 SQL”更新業務數據,在業務數據更新之后,再將其保存成“after image”,最后生成行鎖。以上操作全部在一個數據庫事務內完成,這樣保證了一階段操作的原子性。

 二階段提交

   二階段如果是提交的話,因為“業務 SQL”在一階段已經提交至數據庫, 所以 Seata 框架只需將一階段保存的快照數據和行鎖刪掉,完成數據清理即可。

 

 

 二階段回滾:

     二階段如果是回滾的話,Seata 就需要回滾一階段已經執行的“業務 SQL”,還原業務數據。回滾方式便是用“before image”還原業務數據;但在還原前要首先要校驗臟寫,對比“數據庫當前業務數據”和 “after image”,如果兩份數據完全一致就說明沒有臟寫,可以還原業務數據,如果不一致就說明有臟寫,出現臟寫就需要轉人工處理。

 

 

 3、並發事務的隔離處理:  

  寫隔離:

       正常提交:

 

 

      tx1先開啟本地事務,拿到本地鎖; tx1更新操作 m = 1000-100 = 900; tx1拿到記錄的全局行鎖 ; tx1本地提交,釋放本地鎖  tx2開啟本地事務,拿到本地鎖; tx2更新操作 m = 900-100 = 800。 tx2嘗試拿該記錄的全局行鎖; tx2重試等待全局鎖 (tx1全局提交前,全局鎖被 tx1 持有)  tx1全局提交,釋放全局鎖; tx2拿到記錄的全局行鎖; tx2本地提交,釋放本地鎖; tx2全局提交,釋放全局行鎖。

    數據回滾:

 

 

 

      tx1獲得全局鎖,二階段全局回滾,需獲取本地鎖; tx2持有本地鎖,等待全局行鎖。  tx1分支回滾失敗,一直重試;  tx2等待全局行鎖超時; tx2回滾本地事務,釋放本地鎖; tx1獲取本地鎖,回滾成功。 tx1全局回滾,釋放全局行, 整個過程全局鎖一直被 tx1 持有,所以不會發生臟寫的問題。

   讀隔離:

       AT 模式默認全局隔離級別是讀未提交 。如果應用在特定場景下,必需全局讀已提交,Seata方式是通過 SELECT FOR UPDATE 語句代理。  SELECT FOR UPDATE 語句執行會自動申請全局行鎖,如果全局鎖被其他事務持有,則釋放本地鎖(回滾 SELECT FOR UPDATE 語句的本地執行)並重試。  這個過程中,查詢是被 block 住的,直到全局行鎖拿到,即讀取的相關數據是已提交的才返回。

4、適用場景:

   分布式事務的業務邏輯中僅僅純數據庫操作,不包含其他中間件事務邏輯。

   優勢:

   改動及代碼侵入最小。由Seata來負責Commit和Rollback的自動化觸發或回滾操作。

   劣勢

   1、如果事務中包含緩存存儲或發送EQ消息等不適合。

   2、為了保證鏡像sql的可靠性,需要用戶對sql盡量做簡化, 建議做法:將多條SQL語句分解為多個事務中的原子步驟(對應SeataAt模式的分支Branch概念),如果單條SQL語句跨表,也分解成為多個事務中的原子步驟(盡量降低Seata存儲鏡前SQL結果時的風險)。

   3、多次對DB的操作,以及全局行鎖的存在對並發處理性能有影響。

   4、在二階段未回滾前,都是commit狀態,在回滾前,其他線程出現臟讀,出現臟寫需要人工處理。

4、TCC模式介紹

 該模式由螞蟻金服貢獻。TCC 模式需要用戶根據自己的業務場景實現 Try、Confirm 和 Cancel 三個操作;事務發起方在一階段執行 Try 方式,在二階段提交執行 Confirm 方法,二階段回滾執行 Cancel 方法。

 

整體流程圖:

TCC 三個方法描述:

  • Try:資源的檢測和預留;
  • Confirm:執行的業務操作提交;要求 Try 成功 Confirm 一定要能成功;
  • Cancel:預留資源釋放;

TCC典型業務場景分析:

轉賬場景:A賬戶扣錢,B賬戶加錢;

賬戶 A 上有 100 元,要扣除其中的 30 元 :

       如上圖所示,Try 方法作為一階段准備方法,需要做資源的檢查和預留。

      在扣錢場景下,Try 要做的事情是就是檢查賬戶余額是否充足,預留轉賬資金,預留的方式就是凍結 A 賬戶的 轉賬資金。Try 方法執行之后,賬號 A 余額雖然還是 100,但是其中 30 元已經被凍結了,不能被其他事務使用。         二階段 Confirm 方法執行真正的扣錢操作。Confirm 會使用 Try 階段凍結的資金,執行賬號扣款。Confirm 方法執行之后,賬號 A 在一階段中凍結的 30 元已經被扣除,賬號 A 余額變成 70 元 。

      如果二階段是回滾的話,就需要在 Cancel 方法內釋放一階段 Try 凍結的 30 元,使賬號 A 的回到初始狀態,100 元全部可用。

TCC 設計要點:

   允許空回滾:

    狀態: try未執行,收到cancel請求

    原因:

           Try超時(網絡丟包)---->分布式事務回滾,觸發cancel---->未收到try,收到cancel

    解決方案:

    Cancel 接口設計時需要允許空回滾。在 Try 接口因為丟包時沒有收到,事務管理器會觸發回滾,這時會觸發         Cancel 接口,這時 Cancel 執行時發現沒有對應的事務 xid 或主鍵時,需要返回回滾成功。讓事務服務管理器       認為已回滾。

     

    防懸掛控制:

      狀態:Cancel比Try先執行

   

     原因:

          Try超時(網絡擁堵)------> 分布式事務回滾,觸發cancel----->擁堵的Try到達

    解決方案:

    首先Cancel 接口設計時需要允許空回滾。在 Cancel 空回滾返回成功之前先記錄該條事務 xid 或業務主鍵,標識這條記錄已經回滾過,Try 接口先檢查這條事務xid或業務主鍵如果已經標記為回滾成功過,則不執行Try 的業務操作。

   冪等處理:

     Try、Confirm、Cancel三個方法均要保證冪等性。

 

 

TCC適用場景:

     分布式事務的業務邏輯中除了數據庫操作外,包含其他中間件事務邏輯。

優勢:

    1、用戶可以自己定義業務的補償邏輯,由業務層保證事務的一致性;

    2、適合微服務化場景;

    3、無 AT 模式的全局行鎖,TCC 性能會比 AT 模式高很多。

劣勢:

     1、需要考慮如何將業務模型拆成 2 階段,實現成 TCC 的 3 個方法,並且保證 Try 成功 Confirm 一定能成功,Confirm失敗會不斷重試。

     2、TCC 模式下開發者需要自行實現try,confirm,cancel接口,對業務代碼有一定的侵入性。

 

4、Seata的saga模式

Saga 模式介紹:

      Saga 模式是Seata的長事務解決方案,由螞蟻金服主要貢獻。在 Saga 模式下,分布式事務內有多個參與者,每一個參與者都是一個沖正補償服務,需要用戶根據業務場景實現其正向操作和逆向回滾操作。

Saga模式機制:

     

 

 

      分布式事務執行過程中,依次執行各參與者的正向操作,如果所有正向操作均執行成功,那么分布式事務提交。如果任何一個正向操作執行失敗,那么分布式事務會去退回去執行前面各參與者的逆向回滾操作,回滾已提交的參與者,使分布式事務回到初始狀態。

       Saga 模式下分布式事務通常是由事件驅動的,各個參與者之間是異步執行的,Saga 模式是一種長事務解決方案。

Saga設計要點:

允許空補償:

      狀態:原服務未執行,補償服務執行了。

      原因:

              原服務超時(丟包)---> Saga事務觸發回滾 ---->  未收到原服務的請求,先收到補償請求。

      解決方案:允許空補償。

防懸掛控制

       狀態:補償服務比原服務先執行。

       原因:

                原服務超時(網絡擁堵)-----> Saga事務回滾-----> 先進行補償操作以后,擁堵的原服務到達。

      解決方案:允許空回滾,拒絕空回滾以后原服務的執行。

冪等控制:

      原服務和補償服務支持冪等操作。

自定義事務恢復策略:

      1、Saga事務不保證隔離性,在極端情況下會出現由於臟寫導致無法完成回滾補償操作,此時狀態機引擎可以“重試”繼續往前完成這個分布式事務。由於整個業務流程是由狀態機編排的,即使是事后恢復也可以繼續往前重試。

     2、 用戶可以基於業務特點配置該流程的事務處理策略是優先“回滾”還是“重試”,當事務超時,seata會基於用戶配置的策略不斷進行重試。

使用建議:

        由於 Saga 不保證隔離性,所以我們在業務設計的時候需要做到“寧可長款,不可短款”的原則,長款是指在出現差錯的時候站在我方的角度錢多了的情況,錢少了則是短款,因為如果長款可以給客戶退款,而短款則可能錢追不回來了,也就是說在業務設計的時候,一定是先扣客戶帳再入帳,如果因為隔離性問題造成覆蓋更新,也不會出現錢少了的情況。

 

適用場景:

      1、長流程事務、不需馬上返回最終結果,只要保證最終一致性的場景,

      2、對數據隔離性要求不高,對性能要求高的場景。

      3、事務參與者可能是其它公司的服務或者是遺留系統的服務,無法進行改造和提供 TCC 要求的接口。

優勢:

      事件驅動、無全局鎖、異步、高吞吐、性能高,補償易實現。

劣勢:

      自己寫補償邏輯,沒有事務隔離性。

 

 5.Seata XA模式

也是我們常說的二階段提交,XA要求數據庫本身提供對規范和協議的支持。XA也是對業務代碼無侵入性的

 

XA是全局一致性:在提交階段也會鎖定數據(與AT的區別)

 

優勢:

XA是由數據庫自身所支持的(鎖存儲在各個本地數據庫中),所以入侵性最小,使用成本最低

數據全局一致

 

缺點:

XA協議阻塞帶來性能下降的比較厲害,分支事務越多,性能越差。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM