分布式事務(wù)原理簡(jiǎn)單寫(xiě)起來(lái)全是坑!_第1頁(yè)
分布式事務(wù)原理簡(jiǎn)單寫(xiě)起來(lái)全是坑!_第2頁(yè)
分布式事務(wù)原理簡(jiǎn)單寫(xiě)起來(lái)全是坑!_第3頁(yè)
分布式事務(wù)原理簡(jiǎn)單寫(xiě)起來(lái)全是坑!_第4頁(yè)
分布式事務(wù)原理簡(jiǎn)單寫(xiě)起來(lái)全是坑!_第5頁(yè)
已閱讀5頁(yè),還剩13頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

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

2、們先理解MySQL中的XA是怎么一回事,把 MySQL中的XA搞清楚了,再來(lái)學(xué)習(xí)Seata中的XA模式就容易的多了。.什么是XA規(guī)范什么是兩階段提交我們先來(lái)稍微回顧一下兩階段提交。先來(lái)看下面一張圖: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ù)回滾有三個(gè) 參數(shù):第一個(gè)參數(shù),是以gtridjength為依據(jù),從data字符串上截取下來(lái)的 值;第二個(gè)參數(shù),是第一個(gè)從data上截取下來(lái)值之后,data剩余的值,在本 案例中,第一次被截取之后,就不剩了,所以第二個(gè)參數(shù)是一個(gè)空字符串;第三 個(gè)參數(shù)是formatID的值?;貪L之后,再執(zhí)行X。皿over就看不到東西了。2.4小結(jié) 在用一個(gè)客戶端環(huán)境下,XA事

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

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

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

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

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

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

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

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

13、依賴,而且版本號(hào)是沒(méi)有問(wèn)題的!所以小伙伴們千萬(wàn)別自 己手動(dòng)加druid依賴,可能會(huì)因?yàn)榘姹咎?hào)問(wèn)題掉坑。1.關(guān)掉數(shù)據(jù)源代碼接下來(lái)就是關(guān)閉掉seata數(shù)據(jù)源代理了,account、storage以及order里邊 都改一下,加入如下配置:seata.eiable -auto -data -source -proxg = fake1.配置自定義數(shù)據(jù)源接下來(lái)就是配置自定義數(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,看名字就知道,這就會(huì)把事務(wù)切換為XA模式,最后,還 需要基于DataSourceProxyXA來(lái)配置一下MyBatis,都是常規(guī)操作,不多說(shuō)。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、涉及到三個(gè)概念:AP:這個(gè)不用多說(shuō),AP就是應(yīng)用程序本身。RM: RM是資源管理器,也就是事務(wù)的參與者,大局部情況下就是指數(shù) 據(jù)庫(kù),一個(gè)分布式事務(wù)往往涉及到多個(gè)RMoTM: TM就是事務(wù)管理器,創(chuàng)立分布式事務(wù)并協(xié)調(diào)分布式事務(wù)中的各個(gè) 子事務(wù)的執(zhí)行和狀態(tài),子事務(wù)就是指在RM上執(zhí)行的具體操作。那么什么是兩階段(Two-Phase Commit,簡(jiǎn)稱2PC)提交??jī)呻A段提交說(shuō)白了道理很簡(jiǎn)單,松哥舉個(gè)簡(jiǎn)單例子來(lái)和大家說(shuō)明兩階段提交: 比方下面一張圖:我們?cè)贐usiness中分別調(diào)用Storage與Order、Account,這三個(gè)中的操作要 同時(shí)成功或者同時(shí)失敗,但是由于這三個(gè)分處于不同服務(wù),因此我們

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

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

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

21、交時(shí),需要將提交信 息寫(xiě)入二進(jìn)制日志,這就是一個(gè)分布式內(nèi)部XA事務(wù),只不過(guò)二進(jìn)制日志的參 與者是MySQL本身。MySQL在XA事務(wù)中扮演的是一個(gè)參與者的角色,而 不是協(xié)調(diào)者。2. MySQL 中的 XA接下來(lái)松哥通過(guò)一個(gè)簡(jiǎn)單的例子先給大家看下MySQL中的XA是怎么玩的。兩階段事務(wù)提交比方說(shuō)轉(zhuǎn)賬操作,我用MySQL中的XA事務(wù)來(lái)和大家演示一下從一個(gè)賬戶中轉(zhuǎn)出10塊錢(qián):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ù)提交是一個(gè)兩階段事務(wù)提交的案例。具體執(zhí)行步驟如下:XA START八這個(gè)表示開(kāi)啟一個(gè)XA事務(wù),后面的字符串是事務(wù)的xid,這是一個(gè)唯一字符串,開(kāi)啟之后,事務(wù)的狀態(tài)變?yōu)锳CTME。update account set 4M。八=作。八where “cc?!卑薩八。=A; 這個(gè)表不技(彳丁具體的SQLoXA END trzmsfeQMO八eg:這個(gè)表示結(jié)束一k個(gè)XA事務(wù),此時(shí)事務(wù)的狀態(tài) 轉(zhuǎn)為IDLE。XA PREPARE此小八sfcRw八沔:這個(gè)將事務(wù)置為PREPARE狀態(tài)。XA COMMIT tnmsfe-vo八cg:這個(gè)用來(lái)提交事務(wù),提交之后,事務(wù)的狀態(tài) 就是 COMMITEDo最后一步

24、,可以通過(guò)XA COMMIT來(lái)提交,也可以通過(guò)XA ROLLBACK來(lái)回滾,回 滾后事務(wù)的狀態(tài)就是ROLLBACKo另外第四步可以省略,即一個(gè)IDLE狀態(tài)的XA事務(wù)可以直接提交或者回滾。我們來(lái)看下面一張流程圖:從這張圖里我們可以看出,事務(wù)可以一步提交,也可以兩階段提交,都是支持的。 如果是兩階段提交,prepare之后,其實(shí)是在等其他的資源管理器(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. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論