分布式事務(wù)原理簡單寫起來全是坑!_第1頁
分布式事務(wù)原理簡單寫起來全是坑!_第2頁
分布式事務(wù)原理簡單寫起來全是坑!_第3頁
分布式事務(wù)原理簡單寫起來全是坑!_第4頁
分布式事務(wù)原理簡單寫起來全是坑!_第5頁
已閱讀5頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、分布式事務(wù),我們已經(jīng)給小伙伴介紹了整體內(nèi)容:一文搞明白分布式事務(wù)解決方案!真的so easy!AT模式的實現(xiàn):.手把手帶著小伙伴們寫一個分布式事務(wù)案例!AT模式在多數(shù)據(jù)源中的應(yīng)用:Spring Boot多數(shù)據(jù)源如何處理事務(wù)?教你一招!TCC模式的實現(xiàn):聽說TCC不支持OpenFeign?這個坑松哥必須給大家填了!今天我們就一起來看下另一種模式,XA模式!其實我覺得seata中的四種不同的分布式事務(wù)模式,學(xué)完AT、TCC以及XA 就夠了,Saga不好玩,而且長事務(wù)本身就有很多問題,也不推薦使用。Seata中的XA模式實際上是基于MySQL的XA兩階段提交開展出來的,所 以學(xué)習(xí)XA模式,需要小伙伴

2、們先理解MySQL中的XA是怎么一回事,把 MySQL中的XA搞清楚了,再來學(xué)習(xí)Seata中的XA模式就容易的多了。.什么是XA規(guī)范什么是兩階段提交我們先來稍微回顧一下兩階段提交。先來看下面一張圖:mysql xa start Mtransfer.money11;Query OK, 0 rows affected (0.00 sec)mysql update account set balance=balance-10 where name=zhang:Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings:

3、 0mysql xa end Htransfer_moneyM;Query OK, 0 rows affected (0.00 sec)mysql xa prepare Mtransfer_moneyM; Query OK, 0 rows affected (0.00 sec) TOC o 1-5 h z mysql xa recover; +| formatID | gtrid_length | bqual_length | data|+|1 |14 |0 | transfer.money |+1 row in set (0.00 sec)mysql xa rollback 1transfe

4、r-money1f11fl; Query 0Kf 0 rows affected (0.00 sec)mysql xa recover;Empty set (0.00 sec)小伙伴們看到,皿omch可以查看處于prepare狀態(tài)的事務(wù),事務(wù)回滾有三個 參數(shù):第一個參數(shù),是以gtridjength為依據(jù),從data字符串上截取下來的 值;第二個參數(shù),是第一個從data上截取下來值之后,data剩余的值,在本 案例中,第一次被截取之后,就不剩了,所以第二個參數(shù)是一個空字符串;第三 個參數(shù)是formatID的值?;貪L之后,再執(zhí)行X。皿over就看不到東西了。2.4小結(jié) 在用一個客戶端環(huán)境下,XA事

5、務(wù)和本地(非XA)事務(wù)互相排斥,如果已經(jīng)通過 XA START來開啟一個事務(wù),那么本地事務(wù)不會被啟動,直到XA事務(wù)被提交或 者被回滾為止。相反的,如果已經(jīng)使用START TRANSACTION啟動一個本地事務(wù),那么XA語句 不能被使用,直到該事務(wù)被提交或者回滾為止,而且XA事務(wù)僅僅被InnoDB 存儲引擎支持。Seata 中的 XASeata中的XA模式我們先來看一點理論知識,3.3小節(jié)我們再來看代碼實踐。通過上面的介紹,大家已經(jīng)知道了 MySQL中的XA事務(wù)是怎么回事了,Seata 中的XA模式其實就是在MySQL中XA模式的基礎(chǔ)上實現(xiàn)的。Seata中的 XA模式就是在Seata定義的分布式

6、事務(wù)框架內(nèi),利用事務(wù)資源(數(shù)據(jù)庫、消 息服務(wù)等)對XA協(xié)議的支持,以XA協(xié)議的機制來管理分支事務(wù)的一種事務(wù) 模式。我們來看下面一張圖:MXA CommitXA RollbackXA PrepareXA CommitGlobal TransactionBranchXA PrepareBranch Transstion M StartM EndXA RollbackXA Rollback我來大概說一下這個執(zhí)行步驟:.首先由TM開啟全局分布式事務(wù)。.各個業(yè)務(wù)SQL分別放在不同的XA分支中進行,具體執(zhí)行的流程就 是XA Start-業(yè)務(wù)SQL-XA End,這個流程跟我2.1小節(jié)和大家演示的 MySQ

7、L中XA事務(wù)的流程是一致的。.分支中的XA事務(wù)執(zhí)行完成后,執(zhí)行XAp七i七,并將自己執(zhí)行的狀態(tài)報 告給TCo.其他的分支事務(wù)均按照2、3步驟來執(zhí)行。.當(dāng)所有分支事務(wù)都執(zhí)行完畢后,TC也收到了各個分支事務(wù)報告上來的執(zhí) 行狀態(tài),如果所有狀態(tài)都0K,那么TC通知所有RM執(zhí)行XA ConAHAit完 成事務(wù)的最終提交,否那么TC通知所有RM執(zhí)行XAR。他ack進行事務(wù)回 滾。這就是Seata中的XA模式!只要小伙伴們理解了 2.2小節(jié)中MySQL的 XA模式,那么Seata中的XA模式就很好理解了。特色前面小伙伴們已經(jīng)學(xué)會了 AT和TCC兩種不同的分布式事務(wù)模式了,現(xiàn)在再加 入一個XA,我們再來把這三

8、個放在一起比擬下。AT和TCC都是通過反向補償將數(shù)據(jù)復(fù)原的,也就是說,通過一條更新 語句將數(shù)據(jù)復(fù)原;XA因為是MySQL自己的功能,所以不是反向補償, 而是正兒八經(jīng)的回滾(處于prepare狀態(tài)的數(shù)據(jù)并沒有commit,將來 在二階段可以選擇commit或者rollback)。AT和XA模式是無侵入的分布式事務(wù)解決方案,適用于不希望對業(yè)務(wù)進 行改造的場景,幾乎0學(xué)習(xí)本錢;TCC那么有一定的代碼侵入。AT和XA都是一種全自動的,無論是提交呀,回滾呀(無論是真回滾還 是反向補償),都是全自動的,就是開發(fā)者基本上不需要額外做什么事情; TCC那么是一種手動的分布式事務(wù),一階段的prepare、二階段

9、的commit 或者rollback,所有邏輯都是開發(fā)者自己寫的。松哥發(fā)前面文章的時候,有小伙伴提到分布式事務(wù)的一致性問題,XA模 式是分布式強一致性的解決方案,但是因為性能低而導(dǎo)致使用較少。好啦,比擬完啦,那就上代碼吧!代碼實踐小伙伴們只需要搞明白前面的AT模式后,XA模式其實跟AT模式差不多! 就是替換一下數(shù)據(jù)源即可!話是這么說,不過真做起來,還是有很多坑,我們一 起來看下。為了方便大家理解,本文我就不重新搞案例了,咱們還用上篇文章那個下訂單的 案例來演示。這是一個商品下單的案例,一共有五個服務(wù),我來和大家稍微解釋下:eureka:這是服務(wù)注冊中心。account:這是賬戶服務(wù),可以查詢/

10、修改用戶的賬戶信息(主要是賬戶余 額)。order:這是訂單服務(wù),可以下訂單。storage:這是一個倉儲服務(wù),可以查詢/修改商品的庫存數(shù)量。bussiness:這是業(yè)務(wù),用戶下單操作將在這里完成。這個案例講了一個什么事呢?當(dāng)用戶想要下單的時候,調(diào)用了 bussiness中的接口,bussiness中的接口又 調(diào)用了它自己的service,在service中,首先開啟了全局分布式事務(wù),然后 通過feign調(diào)用storage中的接口去扣庫存,然后再通過feign調(diào)用 order中的接口去創(chuàng)立訂單(order在創(chuàng)立訂單的時候,不僅會創(chuàng)立訂單,還 會扣除用戶賬戶的余額),在這個過程中,如果有任何一個

11、環(huán)節(jié)出錯了(余額 缺乏、庫存缺乏等導(dǎo)致的問題),就會觸發(fā)整體的事務(wù)回滾。本案例具體架構(gòu)如下列圖:這個案例就是一個典型的分布式事務(wù)問題,storage、order以及account中的 事務(wù)分屬于不同的微服務(wù),但是我們希望他們同時成功或者同時失敗。這個案例的基本架構(gòu)我這里就不重復(fù)搭建了,小伙伴們可以參考上篇文章,這里 我們主要來看XA事務(wù)如何添加進來。數(shù)據(jù)庫配置由于XA模式利用的是MySQL自身對XA規(guī)范的實現(xiàn),所以XA機制實際上是不需要undo_log表的,小伙伴們可以把你AT模式中的undojog表刪除啦如果刪除后運行Java程序報錯,那說明你的XA模式使用的不地道! 注意看松哥后面的講解哦

12、。接下來我就來說幾個要點。1.數(shù)據(jù)庫驅(qū)動這是一個坑。松哥經(jīng)過反復(fù)測試,seata中的XA模式和最新版的MySQL驅(qū) 動不兼容,運行時候會有錯誤,經(jīng)過測試,這個版本的驅(qū)動是沒 問題的,所以在account、storage以及order三個需要數(shù)據(jù)庫調(diào)用的服務(wù)上, 記得修改一下數(shù)據(jù)庫驅(qū)動依賴的版本號:dope八4c八egiysql-coectoir-javascope,八力iMCMedio八1. druid 依賴有的小伙伴們看到這里用到了阿里的Druid數(shù)據(jù)庫連接池,就趕緊加入這個依 賴!殊不知,這又掉入版本兼容的坑了,卯川八0-404-5出匕-.(曲她“-$0g1依賴中 實際上包含了 druid

13、依賴,而且版本號是沒有問題的!所以小伙伴們千萬別自 己手動加druid依賴,可能會因為版本號問題掉坑。1.關(guān)掉數(shù)據(jù)源代碼接下來就是關(guān)閉掉seata數(shù)據(jù)源代理了,account、storage以及order里邊 都改一下,加入如下配置:seata.eiable -auto -data -source -proxg = fake1.配置自定義數(shù)據(jù)源接下來就是配置自定義數(shù)據(jù)源了,account、order以及storage都要配置,如 下:C。八八public class DataSoixrccC。八figurati。八(Bcn 八C。八 fig(A%cti。八 Pn)pcrtics(pHcfix

14、= u spring.datasource11public DruidPataSoiArce druidDataSoiArceC) return new DruidDataSoarceO;)13eai(udataSoo(rceProxy,y) Primarypublic PataSource dataSource(Pr(AidPataSob(rce dmidDataSource return new DataSo(ArceProxyXA(drL(idIataSoiArce);)public Sq/Scssi。八Factorg sq(Sessi。八FactoYg(DataSob(匕。dataSo

15、urceProxy)tlarowsExceptionSqlSessioiFactoryBeai sq/Sessi。八FactorgBea八 二 new Sq/Sessi。八FactorgBea八();sq/Scssi。八 FactorgBe4 八 KetDataSorcc(d4taS0Proxg);sq/Sessi。八 FdctorgBeq 八 sctTVa 八 64cti。八 Factory(八 cwSprigMaiagedTraactioiFactoryO);return sq/Sessi。八RictorgBeM.gct。詠ct();)先配置DruidDataSource,但這不是我們最終

16、目的,最終目的是配置DataSourceProxyXA,看名字就知道,這就會把事務(wù)切換為XA模式,最后,還 需要基于DataSourceProxyXA來配置一下MyBatis,都是常規(guī)操作,不多說。1.AP usesresources froma set of RMsApplicationProgram(AP)2.AP defines transac boundaries through the TX interfResourceManagers(RMs)TransactionManager(TM)3.TM and RMs exchangetransaction information這張圖里

17、涉及到三個概念:AP:這個不用多說,AP就是應(yīng)用程序本身。RM: RM是資源管理器,也就是事務(wù)的參與者,大局部情況下就是指數(shù) 據(jù)庫,一個分布式事務(wù)往往涉及到多個RMoTM: TM就是事務(wù)管理器,創(chuàng)立分布式事務(wù)并協(xié)調(diào)分布式事務(wù)中的各個 子事務(wù)的執(zhí)行和狀態(tài),子事務(wù)就是指在RM上執(zhí)行的具體操作。那么什么是兩階段(Two-Phase Commit,簡稱2PC)提交?兩階段提交說白了道理很簡單,松哥舉個簡單例子來和大家說明兩階段提交: 比方下面一張圖:我們在Business中分別調(diào)用Storage與Order、Account,這三個中的操作要 同時成功或者同時失敗,但是由于這三個分處于不同服務(wù),因此我們

18、只能先讓這 三個服務(wù)中的操作各自執(zhí)行,三個服務(wù)中的事務(wù)各自執(zhí)行就是兩階段中的第一階 段。第一階段執(zhí)行完畢后,先不要急著提交,因為三個服務(wù)中有的可能執(zhí)行失敗了, 此時需要三個服務(wù)各自把自己一階段的執(zhí)行結(jié)果報告給一個事務(wù)協(xié)調(diào)者(也就是前面文章中的Seata Server),事務(wù)協(xié)調(diào)者收到消息后,如果三個服務(wù)的一階段 都執(zhí)行成功了,此時就通知三個事務(wù)分別提交,如果三個服務(wù)中有服務(wù)執(zhí)行失敗 了,此時就通知三個事務(wù)分別回滾。這就是所謂的兩階段提交??偨Y(jié)一下:兩階段提交中,事務(wù)分為參與者(例如上圖的各個具體服務(wù))與協(xié)調(diào) 者(上文案例中的Seata Server),參與者將操作成敗通知協(xié)調(diào)者,再由協(xié)調(diào)者 根

19、據(jù)所有參與者的反應(yīng)情報決定各參與者是要提交操作還是中止操作,這里的參 與者可以理解為RM,協(xié)調(diào)者可以理解為TMo不過Seata中的各個分布式事務(wù)模式,基本都是在二階段提交的基礎(chǔ)上演化出 來的,因此并不完全一樣,這點需要小伙伴們注意。1.2什么是XA規(guī)范XA規(guī)范是X/Open組織定義的分布式事務(wù)處理(DTP, Distributed Transaction Processing)標(biāo)準(zhǔn)。XA規(guī)范描述了全局的事務(wù)管理器與局部的資源管理器之間的接口。XA規(guī)范的 目的是允許多個資源(如數(shù)據(jù)庫,應(yīng)用服務(wù)器,消息隊列等)在同一事務(wù)中訪問, 這樣可以使ACID屬性跨越應(yīng)用程序而保持有效。XA規(guī)范使用兩階段提交

20、來保證所有資源同時提交或回滾任何特定的事務(wù)。XA規(guī)范在上世紀(jì)90年代初就被提出。目前,幾乎所有主流的數(shù)據(jù)庫都對XA 規(guī)范提供了支持。XA事務(wù)的基礎(chǔ)是兩階段提交協(xié)議。需要有一個事務(wù)協(xié)調(diào)者來保證所有的事務(wù)參 與者都完成了準(zhǔn)備工作(第一階段)。如果協(xié)調(diào)者收到所有參與者都準(zhǔn)備好的消息, 就會通知所有的事務(wù)都可以提交了(第二階段)。MySQL在這個XA事務(wù)中扮 演的是參與者的角色,而不是協(xié)調(diào)者(事務(wù)管理器)。MySQL的XA事務(wù)分為內(nèi)部XA和外部XA。外部XA可以參與到外部的分 布式事務(wù)中,需要應(yīng)用層介入作為協(xié)調(diào)者;內(nèi)部XA事務(wù)用于同一實例下跨多 引擎事務(wù),由Binlog作為協(xié)調(diào)者,比方在一個存儲引擎提

21、交時,需要將提交信 息寫入二進制日志,這就是一個分布式內(nèi)部XA事務(wù),只不過二進制日志的參 與者是MySQL本身。MySQL在XA事務(wù)中扮演的是一個參與者的角色,而 不是協(xié)調(diào)者。2. MySQL 中的 XA接下來松哥通過一個簡單的例子先給大家看下MySQL中的XA是怎么玩的。兩階段事務(wù)提交比方說轉(zhuǎn)賬操作,我用MySQL中的XA事務(wù)來和大家演示一下從一個賬戶中轉(zhuǎn)出10塊錢:mysql XA START Mtransfer_moneyM;Query OK, 0 rows affected (0.00 sec) mysql update account set amount=amount-10 whe

22、re account_no=Query OK, 1 row affected (000 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql XA Query OK,END Mtransfer_moneyM; 0 rows affected (0.00 sec) mysql XA PREPARE transfejmoney” ;Query 0Kf 0 rows affected (0.00 sec)mysql XA COMMITQuery OK, 0 rowstransfer_money11;affected (0.00 sec) mysql |上面這

23、段事務(wù)提交是一個兩階段事務(wù)提交的案例。具體執(zhí)行步驟如下:XA START八這個表示開啟一個XA事務(wù),后面的字符串是事務(wù)的xid,這是一個唯一字符串,開啟之后,事務(wù)的狀態(tài)變?yōu)锳CTME。update account set 4M。八=作。八where “cc?!卑薩八。=A; 這個表不技(彳丁具體的SQLoXA END trzmsfeQMO八eg:這個表示結(jié)束一k個XA事務(wù),此時事務(wù)的狀態(tài) 轉(zhuǎn)為IDLE。XA PREPARE此小八sfcRw八沔:這個將事務(wù)置為PREPARE狀態(tài)。XA COMMIT tnmsfe-vo八cg:這個用來提交事務(wù),提交之后,事務(wù)的狀態(tài) 就是 COMMITEDo最后一步

24、,可以通過XA COMMIT來提交,也可以通過XA ROLLBACK來回滾,回 滾后事務(wù)的狀態(tài)就是ROLLBACKo另外第四步可以省略,即一個IDLE狀態(tài)的XA事務(wù)可以直接提交或者回滾。我們來看下面一張流程圖:從這張圖里我們可以看出,事務(wù)可以一步提交,也可以兩階段提交,都是支持的。 如果是兩階段提交,prepare之后,其實是在等其他的資源管理器(RM)反應(yīng) 結(jié)果。事務(wù)直接提交松哥再給大家演示一下事務(wù)一步提交:(mysql XA START Htransfer_money11;Query OK, 0 rows affected (0.00 sec)mysql update account set amount=amount-10 where account。二Query OK, 1 row affected (0.00 sec)Rows matched: 1 Changed: 1 Warnings: 0mysql XA END ,transfer_moneyH;Query OK, 0 rows affected (0.00 sec)mysql XA COMMIT tra

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論