![金融項目-課件分布式事務(wù)_第1頁](http://file4.renrendoc.com/view14/M00/23/10/wKhkGWcNe5uADuEAAAJYKDim5Hk753.jpg)
![金融項目-課件分布式事務(wù)_第2頁](http://file4.renrendoc.com/view14/M00/23/10/wKhkGWcNe5uADuEAAAJYKDim5Hk7532.jpg)
![金融項目-課件分布式事務(wù)_第3頁](http://file4.renrendoc.com/view14/M00/23/10/wKhkGWcNe5uADuEAAAJYKDim5Hk7533.jpg)
![金融項目-課件分布式事務(wù)_第4頁](http://file4.renrendoc.com/view14/M00/23/10/wKhkGWcNe5uADuEAAAJYKDim5Hk7534.jpg)
![金融項目-課件分布式事務(wù)_第5頁](http://file4.renrendoc.com/view14/M00/23/10/wKhkGWcNe5uADuEAAAJYKDim5Hk7535.jpg)
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1.什么是事務(wù)?舉個生活中的例子:你去商店買東西就是一個事務(wù)的例子,買東西是一個交易,包含“手交錢,一手交貨”1.什么是事務(wù)?舉個生活中的例子:你去商店買東西就是一個事務(wù)的例子,買東西是一個交易,包含“手交錢,一手交貨”作失敗,交易就必須撤銷。系型數(shù)據(jù)庫的事務(wù)又被稱為本地事務(wù)。回顧一下數(shù)據(jù)庫事務(wù)的四大特性A(Atomic)功部分失敗的情況。C(Consistency轉(zhuǎn)100元,轉(zhuǎn)賬前和轉(zhuǎn)賬后的數(shù)據(jù)是正確狀態(tài)這叫一致性,如果出現(xiàn)張三轉(zhuǎn)出100元,李四賬戶沒有增加100元這就出現(xiàn)了數(shù)據(jù)錯誤,就沒有達(dá)到一致性。I(Isolatio):隔離性,數(shù)據(jù)庫中的事務(wù)一般都是并發(fā)的,隔離性是指并發(fā)的兩個事務(wù)的執(zhí)行互不干題。D(Duability滾。微服務(wù)應(yīng)用的演變:成事務(wù)操作,這種分布式系統(tǒng)環(huán)境下的事務(wù)機制稱之為分布式事務(wù)。begin--1.--2.成事務(wù)操作,這種分布式系統(tǒng)環(huán)境下的事務(wù)機制稱之為分布式事務(wù)。begin--1.--2.本地數(shù)據(jù)庫操作:李四增加金額committransaction;begin--1.A--2.A微服務(wù)遠(yuǎn)程調(diào)用B微服務(wù):讓李四增加金額committransaction;因此在分布式架構(gòu)的基礎(chǔ)上,傳統(tǒng)數(shù)據(jù)庫事務(wù)就無法使用了,比如上例,張三和李四的賬戶不在一個數(shù)據(jù)庫中甚至不在一個應(yīng)用系統(tǒng)里,怎么實現(xiàn)轉(zhuǎn)賬事務(wù)?也就是說同樣一個功能,原來是由一個系統(tǒng)完成的,即使這個功能包含很多個操作,也可以采用數(shù)據(jù)庫事務(wù)(本地事務(wù))搞定,而現(xiàn)在這個功能中包含的多個操作可能是由多個系統(tǒng)(微服務(wù))參與完成的,此時數(shù)據(jù)庫事務(wù)(本地事務(wù))的分布式事務(wù)理論來支撐了。從而幫助我們理解每個解決方案。CAP理解求,就需要橫向去擴展幾臺Slave(從數(shù)據(jù)庫)去分擔(dān)求,就需要橫向去擴展幾臺Slave(從數(shù)據(jù)庫)去分擔(dān)Master(主數(shù)據(jù)庫)的壓力。如果服務(wù)對數(shù)據(jù)庫的需求是IO密集型的,那可能會經(jīng)常遇到增刪改影響到了查詢效率。這就需要同步。1、商品服務(wù)請求主數(shù)據(jù)庫寫入商品信息(添加商品、修改商品、刪除商品23C-到的數(shù)據(jù)都是最新的狀態(tài)。12A-Availability上圖中,商品信息讀取滿足可用性就是要實現(xiàn)如下目標(biāo):12P-Partitiontolerance部分還能維持分布式系統(tǒng)的運作,這樣就具有較好的分區(qū)容忍性。1部分還能維持分布式系統(tǒng)的運作,這樣就具有較好的分區(qū)容忍性。122.1.2CAP1、上邊的例子是否同時具備CAP在所有分布式事務(wù)場景中不會同時具備CAP三個特性,因為在具備了P的前提下C和A如果要保證數(shù)據(jù)的一致性就要實現(xiàn)每個節(jié)點的數(shù)據(jù)一致,節(jié)點越多可用性越好,但是數(shù)據(jù)一致性會越差。2、CAP例如:上邊的商品管理,完全可以實現(xiàn)AP最新的即可。通常實現(xiàn)AP都會保證最終一致性,后面講的ASE理論就是根據(jù)AP來擴展的,一些業(yè)務(wù)場景比如:訂單退款,今日退款成功,明日賬戶到賬,只要用戶可以接受在一定時間內(nèi)到賬即可。放棄可用性,追求一致性和分區(qū)容錯性,我們的zooeeper一次轉(zhuǎn)賬請求要等待雙方銀行系統(tǒng)都完成整個事務(wù)才算完成。性。那么系統(tǒng)將不是一個標(biāo)準(zhǔn)的分布式系統(tǒng),我們最常用的關(guān)系型數(shù)據(jù)庫就滿足了CA。上邊的商品管理,如果要實現(xiàn)CA2.1.3通過上面我們已經(jīng)學(xué)習(xí)了CAP理論的相關(guān)知識,CAP是一個已經(jīng)被證實的理論:一個分布式系統(tǒng)最多只能同時滿足一致性(Consistency)、可用性(Availability2.1.3通過上面我們已經(jīng)學(xué)習(xí)了CAP理論的相關(guān)知識,CAP是一個已經(jīng)被證實的理論:一個分布式系統(tǒng)最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partitiontoleance)這三項中的兩項。它可以作為我們進行架構(gòu)設(shè)計、技術(shù)選型的考量標(biāo)準(zhǔn)。對于多數(shù)大型互聯(lián)網(wǎng)應(yīng)用的場景,節(jié)點眾多、部署分散,而且現(xiàn)在的集群規(guī)模越來越大,所以節(jié)點故障、網(wǎng)絡(luò)故障是常態(tài),而且要保證服務(wù)可用性達(dá)到N個9(99.99..%),擇:保證P和A,舍棄C強一致,保證最終一致性。2.2BASE1CAP理論告訴我們一個分布式系統(tǒng)最多只能同時滿足一致性(Consistency)、可用性(Availability)和分區(qū)容忍性(Partitiontoleance)這三項中的兩項,其中AP在實際應(yīng)用中較多,AP保證可用性和分區(qū)容忍性,但是在實際生產(chǎn)中很多場景都要實現(xiàn)一致性,比如前邊我們舉的例子,主數(shù)據(jù)庫向從數(shù)據(jù)庫同步數(shù)據(jù),即使不要一致性,但是最終也要將數(shù)據(jù)同步成功來保證數(shù)據(jù)一致,這種一致性和CAP中的一致性不同,CAP中的一致性要求在任何時間查詢每個節(jié)點數(shù)據(jù)都必須一致,它強調(diào)的是強一致性,但是最終一致性是允許可以在一段時間內(nèi)每個節(jié)點的數(shù)據(jù)不一致,但是經(jīng)過一段時間每個節(jié)點的數(shù)據(jù)必須一致,它強調(diào)的是最終數(shù)據(jù)的一致性。2、BaseASE是BasicallyAvailable(基本可用)、Softstate(軟狀態(tài))和Eventuallyconsistent(最終一致性)短語的縮寫。ASE理論是對CAP中AP的一個擴展,通過犧牲強一致性來獲得可用性,當(dāng)出現(xiàn)故障允許部分不可用但要保證核心功能可用,允許數(shù)據(jù)在一段時間內(nèi)是不一致的,但最終達(dá)到一致狀態(tài)。滿足ASE理論的事務(wù),我們稱之為柔性事務(wù)”。基本可用:分布式系統(tǒng)在出現(xiàn)故障時,允許損失部分可用功能,保證核心功能可用。如,電商網(wǎng)站軟狀態(tài):由于不要求強一致性,所以ASE允許系統(tǒng)中存在中間狀態(tài)(軟狀態(tài)),這個狀態(tài)不影響系統(tǒng)可用性,如訂單的"支付中"、“數(shù)據(jù)同步中”等狀態(tài),待數(shù)據(jù)最終一致后狀態(tài)改為“成功”態(tài)。最終一致:最終一致是指經(jīng)過一段時間后,所有節(jié)點數(shù)據(jù)都將會達(dá)到一致。如訂單的"支付中"狀態(tài),最終會變?yōu)橹Ц冻晒Α被蛘?支付失敗"間的延遲、等待。TCCC(ry/Con?rm/Cancel)編程模式的核心思想是:針對每個分支事務(wù)操作,都要向全局事務(wù)發(fā)起方注冊ry、Con?rm和Cancel執(zhí)行:Try階段主要是做業(yè)務(wù)檢查(一致性)及資源預(yù)留(隔離)Con?rmCon?rm階段主要是做確認(rèn)提交,Try階段所有分支事務(wù)執(zhí)行成功后開始執(zhí)行Con?rm。通常情況下,采用TCC則認(rèn)為Con?rm階段是不會出錯的。即:只要Try成功,Con?rm一定成功。若Cancel放。通常情況下,采用TCC則認(rèn)為Cancel階段也是一定成功的。若Canceltry-con?rm-cancel中,由事務(wù)管理器(協(xié)調(diào)管理)進AB兩個try分別執(zhí)行,在這個過程中,事務(wù)管理器會對AB進行監(jiān)控,一旦任何一方出現(xiàn)了問題,就推進對方執(zhí)行cancel;如果雙方都沒有異常,就推進AB執(zhí)行con?rm。如果在執(zhí)行con?rm或cancel過程中出現(xiàn)問題,就引入重試機制或由人工處理。C解決方案要求每個分支事務(wù)實現(xiàn)三個操作ry/Con?rm/Cancel。try操作做業(yè)務(wù)檢查及資源預(yù)留,Con?rm操作做業(yè)務(wù)確認(rèn)操作,Cancel操作需要實現(xiàn)一個與try相反的操作。TM(事務(wù)管理器)有的分支事務(wù)的try操作,任何一個分支事務(wù)的try操作執(zhí)行失敗,TM將會發(fā)起所有分支事務(wù)的Cancel操作,若try操作全部成功,TM將會發(fā)起所有分支事務(wù)的Con?rm操作,其中Con?rm/Cancel操作若執(zhí)行失敗,TM會進行重試,因此需要實現(xiàn)冪等。ry/Con?rm/Cancel據(jù)業(yè)務(wù)情況靈活掌握。對應(yīng)用的侵入性強。業(yè)務(wù)邏輯的每個分支都需要實現(xiàn)try、con?rm、cancel較強,改造成本高。致性的要求,con?rm和cancel接口必須實現(xiàn)冪等。3.2TCC失敗,TM會進行重試,因此需要實現(xiàn)冪等。ry/Con?rm/Cancel據(jù)業(yè)務(wù)情況靈活掌握。對應(yīng)用的侵入性強。業(yè)務(wù)邏輯的每個分支都需要實現(xiàn)try、con?rm、cancel較強,改造成本高。致性的要求,con?rm和cancel接口必須實現(xiàn)冪等。3.2TCC目前市面上的TCC支持嵌套事務(wù)(Nestedtransactionsupport)采用disruptor框架進行事務(wù)日志的異步讀寫,與RPC支持SpringBoot-starter項目啟動,使用簡單。RPC框架支持:dubbo,motan,springcloud本地事務(wù)存儲支持:redis,mongodb,zookeeper,?le,mysql。事務(wù)日志序列化支持:java,hessian,kryo,protostu?。采用AspectAOP切面思想與Spring無縫集成,天然支持集群。Hmily利用OP透明的調(diào)用到另一方的ry、Conform、Cancel償,重試等。Hmily不需要事務(wù)協(xié)調(diào)服務(wù),但需要提供一個數(shù)據(jù)庫(mysql/mongodb/zooeeper/edis/?le)來進行日志存儲。Hmily實現(xiàn)的C服務(wù)與普通的服務(wù)一樣,只需要暴露一個接口,也就是它的ry業(yè)務(wù)。Con?rm/Cancel業(yè)務(wù)邏輯,只是因為全局事務(wù)提交/回滾的需要才提供的,因此Con?rm/Cancel需要被Hmily事務(wù)框架發(fā)現(xiàn)即可,不需要被調(diào)用它的其他業(yè)務(wù)服務(wù)所感知。官網(wǎng)介紹:/website/zh-本案例通過hmily框架實現(xiàn)C分布式事務(wù),模擬兩個賬戶的轉(zhuǎn)賬交易過程。兩個賬戶分別在不同的銀行(張三在bank、李四在bank2),bank1、bank2成功,要么都失敗。tcc-/changmingxie/tcc-/QNJR-數(shù)據(jù)庫:MySQL5.7.25+JDK:jdk1.8+微服務(wù):數(shù)據(jù)庫:MySQL5.7.25+JDK:jdk1.8+微服務(wù):spring-boot-2.1.3、spring-cloud-hmily:hmily-springcloud.2.0.4-創(chuàng)建bank1CREATEDATABASE`bank1`CHARACTERSET'utf8'COLLATEUSEDROPTABLEIFEXISTS`account_info`;CREATETABLEUSEDROPTABLEIFEXISTS`account_info`;CREATETABLE`account_info`(`id`bigint(20)NOTNULL`account_name`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'戶主姓名',`account_no`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'銀行卡號',`account_password`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'帳戶密碼',`account_balance`doubleNULLDEFAULTNULLCOMMENT'帳戶余額PRIMARYKEY(`id`)USING)ENGINE=InnoDBAUTO_INCREMENT=5CHARACTERSET=utf8COLLATE=ROW_FORMAT=INSERTINTO`account_info`VALUES(1'張三''1'''創(chuàng)建bank2庫,并導(dǎo)入以下表結(jié)構(gòu)和數(shù)據(jù)CREATEDATABASE`bank2`CHARACTERSET'utf8'COLLATEUSEDROPTABLEIFEXISTS`account_info`;CREATETABLE`account_info`(`id`bigint(20)NOTNULL`account_name`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'戶主姓名',`account_no`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'銀行卡號',`account_password`varchar(100CHARACTERSETutf8COLLATEutf8_binNULLDEFAULTNULLCOMMENT'帳戶密碼',`account_balance`doubleNULLDEFAULTNULLCOMMENT'帳戶余額PRIMARYKEY(`id`)USING)ENGINE=InnoDBAUTO_INCREMENT=5CHARACTERSET=utf8COLLATE=ROW_FORMAT=INSERTINTO`account_info`VALUES(2'李四''2'NULLHmilyMavenpom.xml導(dǎo)入hmily(1)application.yml配置(只顯示hmily部分hmily:serializerkryo#retryMax:hmily:serializerkryo#retryMax:30#最大重試次數(shù)repositorySupportdb#持久化方式started:true#事務(wù)發(fā)起方hmilyDbConfig:driverClassName:username:rootpassword:(2)HmilyprivateEnvironmentpublicHmilyTransactionBootstraphmilyTransactionBootstrap(HmilyInitServiceHmilyTransactionBootstraphmilyTransactionBootstrap=HmilyDbConfighmilyDbConfig=newreturnhmilyTransactionBootstrap;(3)feign@FeignClient(value="hmily-demo-bank2")publicinterfaceBank2Client{(3)feign@FeignClient(value="hmily-demo-bank2")publicinterfaceBank2Client{Booleantransfer(@RequestParam("amount")Double(4)privateBank2Client@Hmily(confirmMethod="commit",cancelMethod="rollback")publicvoidprepare(StringaccountNo,doubleamount){System.out.println("...Bank1Serviceprepare...");thrownewRuntimeException("bank2publicvoidcommit(StringaccountNo,doubleamount){System.out.println("...Bank1Servicecommit..."publicvoidrollback(StringaccountNo,doubleamount){accountInfoDao.updateAccountBalance(accountNo,amountSystem.out.println("...Bank1Servicerollback...");(5)@SpringBootApplication(exclude=MongoAutoConfiguration.class)@EnableFeignClients(basePackagespublicclassBank1HmilyServer{publicstaticvoidmain(String[]args){SpringApplication.run(Bank1HmilyServer.class,args);hmily-demo-bank2(1)application.yml配置(只顯示hmily部分hmily-demo-bank2(1)application.yml配置(只顯示hmily部分hmily:serializerkryo#retryMax:30#最大重試次數(shù)repositorySupportdb#持久化方式started:false#事務(wù)參與方hmilyDbConfig:driverClassName:username:rootpassword:Hmily配置類,和hmily-demo-bank1@Hmily(confirmMethod="confirmMethod",cancelMethod=publicBooleanupdateAccountBalance(StringaccountNo,Doubleamount)System.out.println("...Bank2ServiceBegin...");accountInfoDao.updateAccountBalance(accountNo}catch(Exceptione){thrownewRuntimeException(e.getMessage()returnpublicBooleanconfirmMethod(StringaccountNo,Doubleamount){System.out.println("...Bank2Servicecommit...");returnpublicBooleancancelMethod(StringaccountNo,Doubleamount){accountInfoDao.updateAccountBalance(accountNo,amount*-1);System.out.println("...Bank2Servicerollback...");return(4)@SpringBootApplication(exclude=MongoAutoConfiguration.class)publicclassBank2HmilyServer{@SpringBootApplication(exclude=MongoAutoConfiguration.class)publicclassBank2HmilyServer{publicstaticvoidmain(String[]args)3.3.5對應(yīng)的賬號信息,該業(yè)務(wù)存在分布式事務(wù)問題。且屬于執(zhí)行時間較短的業(yè)務(wù)。C方案的軟狀態(tài)時間很短,一致性較強,因此在此業(yè)務(wù),我們選用C型分布式事務(wù)解決方案。4.2Hmily1.新建數(shù)據(jù)庫p2p_undo_log,此庫用來存儲hmily事務(wù)日志,空庫即可,由hmilyCREATEDATABASE`p2p_undo_log`CHARACTERSET'utf8'COLLATE2Maven<artifactId>hmily-<artifactId>hmily-<version>2.0.5-<artifactId>spring-boot-<artifactId>spring-boot-starter-<artifactId>logback-<artifactId>slf4j-<artifactId>logback-<artifactId>spring-(1)在Apollo中,為common-template項目新建公共namespace,命名為micro_service.spring-cloud-org.dromara.hmily.serializer=kryoorg.dromara.hmily.retryMax=30org.dromara.hmily.repositorySupport=dborg.dromara.hmily.started=trueorg.dromara.hmily.hmilyDbConfig.driverClassName=com.mysql.cj.jdbc.Driverorg.dromara.hmily.hmilyDbConfig.url=jdbc:mysql://localhost:3306/p2p_undo_log?org.dromara.hmily.hmilyDbConfig.username=org.dromara.hmily.hmilyDbConfig.password=在consumer-service項目中,關(guān)聯(lián)剛才新建的micro_service.spring-cloud-在application.yml中增加micro_service.spring-cloud-在con?g包中新增HmilypublicclassHmilyConfig在application.yml中增加micro_service.spring-cloud-在con?g包中新增HmilypublicclassHmilyConfig{privateEnvironmentpublicHmilyTransactionBootstraphmilyTransactionBootstrap(HmilyInitServiceHmilyTransactionBootstraphmilyTransactionBootstrap=HmilyDbConfighmilyDbConfig=newreturnhmilyTransactionBootstrap;(4)啟動類上增加org.dromara.hmily@SpringBootApplication(scanBasePackages=(5)Feign代理(AccountApiAgent接口)中增加@HmilypublicinterfaceAccountApiAgent{@PostMapping(value=publicinterfaceAccountApiAgent{@PostMapping(value="/account/l/accounts")RestResponse<AccountDTO>register(@RequestBodyAccountRegisterDTO(6)修改ConsumerServiceImpl代碼,注冊Try、Con?rm、publicvoidregister(ConsumerRegisterDTOconsumerRegisterDTO){...("executeconfirmRegister");("executecancelRegister");4.3.2事務(wù)參與方:account-在Apollo中,為account-service項目關(guān)聯(lián)micro_service.spring-cloud-hmilyorg.dromara.hmily.started=false在application.yml中增加micro_service.spring-cloud-在con?g包中新增Hmily配置類,同consumer-service啟動類上增加org.dromara.hmily@SpringBootApplication(scanBasePackages(5)修改AccountServiceImpl代碼,注冊Try、Con?rm、publicAccountDTOregister(AccountRegisterDTOregisterDTO){...("executeconfirmRegister");("executecancelRegister");//前面在學(xué)習(xí)CAP和ASE理論時,我們得出結(jié)論:一般情況下會保證P和A前面在學(xué)習(xí)CAP和ASE理論時,我們得出結(jié)論:一般情況下會保證P和A,舍棄C,保證最終一致性。最終一致是指經(jīng)過一段時間后,所有節(jié)點數(shù)據(jù)都將會達(dá)到一致。如訂單的"支付中"狀態(tài),最終會變?yōu)椤俺晒Α被蛘?支付失敗",使訂單狀態(tài)與實際交易結(jié)果達(dá)成一致,但需要一定時間的延遲、等待。5.1現(xiàn)最終一致性。以轉(zhuǎn)賬為例:消息發(fā)送方張三,即扣減余額30元,然后通過網(wǎng)絡(luò)發(fā)送消息到消息接收方李四,即通過網(wǎng)絡(luò)從MQ中接收消息,然后增加余額301.發(fā)送成功2.commit異常,數(shù)據(jù)庫回滾,但此時消息已經(jīng)正常發(fā)送了,同樣會導(dǎo)致不一致。行成功分丟失,從而導(dǎo)致消息重復(fù)消費。5.2RocketMQRocketMQ分丟失,從而導(dǎo)致消息重復(fù)消費。5.2RocketMQRocketMQ是一個來自阿里巴巴的分布式消息中間件,于2012年開源,并在2017年正式成為Apache頂級項目。ApacheRocketMQ4.3之后的版本正式支持事務(wù)消息,為分布式事務(wù)實現(xiàn)提供了便1.發(fā)送成功RocetMQ中的Boer與發(fā)送方具備雙向通信能力,使得boer并且RocetMQ本身提供了存儲機制,使得事務(wù)消息可以持久化保存;這些優(yōu)秀的設(shè)計可以保證即使發(fā)生了異常,RocetMQ依然能夠保證達(dá)成事務(wù)的最終一致性。發(fā)送方發(fā)送一個事務(wù)消息給Boe,RocetM會將消息狀態(tài)標(biāo)記為“Pepaed時不能被接收方消費。這樣的消息稱之為HalfMessag,即半消息。Broker若本地事務(wù)執(zhí)行成功,發(fā)送commi消息給Boe,RocetMQ會將消息狀態(tài)標(biāo)記為“可消費”,此ollbac消息給將刪除該消息。如果發(fā)送方在本地事務(wù)過程中,出現(xiàn)服務(wù)掛掉,網(wǎng)絡(luò)閃斷或者超時,那Boe果此時RocketMQ將會不停的詢問發(fā)送方來獲取本地事務(wù)的執(zhí)行狀態(tài)(即事務(wù)回查根據(jù)事務(wù)回查的結(jié)果來決定Commit或Rollback時失敗。以上主干流程已由RocetM查的方法即可,具體來說就是實現(xiàn)下面這個接口:發(fā)送prepare@parammsg回傳的消息,利用transactionId即可獲取到該消息的唯一@paramarg調(diào)用send方法時傳遞的參數(shù),當(dāng)send時候若有額外的參數(shù)可以傳遞到send方法中,@return返回事務(wù)狀態(tài),COMMIT:提交ROLLBACK:回滾UNKNOWObjectarg);2.行成功如果是出現(xiàn)了異常,RocetMQ是超時,2.行成功如果是出現(xiàn)了異常,RocetMQ是超時,RocetMQ就會無限制的消費消息,不斷的去執(zhí)行本地事務(wù),直到成功為止。本實例通過RocetMQ的銀行(張三在bank、李四在bank2),bank1、bank2是兩個相互獨立的微服務(wù)。JDK:64位jdk1.8+@parammsg通過獲取transactionId@return返回事務(wù)狀態(tài),COMMIT:提交ROLLBACK:回滾UNKNOWLocalTransactionStatecheckLocalTransaction(finalMessageExtRocketMQ客戶端:RocketMQ-spring-boot-starter.2.0.2-本案例需要兩個數(shù)據(jù)庫,一個是bank1,一個是bank2,無需創(chuàng)建,直接使用RocketMQ客戶端:RocketMQ-spring-boot-starter.2.0.2-本案例需要兩個數(shù)據(jù)庫,一個是bank1,一個是bank2,無需創(chuàng)建,直接使用Hmily快速入門案例中的數(shù)據(jù)庫即可。另外,為了實現(xiàn)冪等性,需要分別在bank1、bank2數(shù)據(jù)庫中新增de_duplication交易記錄表(去重表)。DROPTABLEIFEXISTS`de_duplication`;CREATETABLE`de_duplication`(`tx_no`bigint(20)NOT`create_time`datetime(0)NULLDEFAULTNULL,PRIMARYKEY(`tx_no`)USINGBTREE)ENGINE=InnoDBCHARACTERSET=utf8COLLATE=utf8_binROW_FORMAT=啟動啟動setROCKETMQ_HOME=[RocketMQ服務(wù)端解壓路徑start[RocketMQ服務(wù)端解壓路徑啟動setROCKETMQ_HOME=[RocketMQ服務(wù)端解壓路徑start[RocketMQ服務(wù)端解壓路徑]/bin/mqbroker.cmd-n:9876Maven消息發(fā)送方1.publicclasspublicclassAccountChangeEventimplementsSerializableprivateStringprivatedoubleprivatelong2.publicinterfaceAccountInfoDao@paramaccountNo@paramamount@Update("updateaccount_infosetaccount_balance=account_balance+#{amount}whereaccount_no=#{accountNo}")intupdateAccountBalance(@Param("accountNo")StringaccountNo,@Param("amount")Doubleamount);@paramaccountNo@Select("select*fromaccount_infowherewhereaccount_no=#{accountNo}")AccountInfofindByIdAccountNo(@Param("accountNo")StringaccountNo);@paramtxNo@Select("selectcount(1)fromde_duplicationwheretx_no=#{txNo}")intisExistTx(longtxNo);@paramtxNo3.publicclassBankMessageProducer3.publicclassBankMessageProducer{privateRocketMQTemplatepublicvoidsendAccountChangeEvent(AccountChangeEventaccountChangeEvent)1.JSONObjectobject=newJSONObject();object.put("accountChange",accountChangeEvent);Message<String>msg=//2.發(fā)送消息msg,null);4.實現(xiàn)業(yè)務(wù)層代碼,分別實現(xiàn)了發(fā)送事務(wù)消息與本地事務(wù)扣減金額,注意更新帳號余額-@paramvoidupdateAccountBalance(AccountChangeEvent更新帳號余額-@paramvoiddoUpdateAccountBalance(AccountChangeEventpublicclassAccountInfoServiceImplimplementsAccountInfoServiceprivateBankMessageProducer更新帳號余額-@paramintaddTx(long更新帳號余額-@param@Transactional(isolation=publicvoiddoUpdateAccountBalance(AccountChangeEventaccountChange)getAmount()*-1);5.實現(xiàn)RocketMQexecuteLocalTransaction,該方法執(zhí)行本地事務(wù),會被RocketMQ@RocketMQTransactionListener(txProducerGroup="producer_ensure_transfer")publicclassTransferTransactionListenerImplimplementsRocketMQLocalTransactionListener{privateAccountInfoService@param@parampublicRocketMQLocalTransactionStateexecuteLocalTransaction(Messagemsg,Objectarg){//1.finalJSONObjectjsonObject=JSON.parseObject(newString((byte[])AccountChangeEventaccountChangeEvent//2.BooleanisCommit=true;try{//2.BooleanisCommit=true;try{}catch(Exceptione){isCommit=return}elsereturn@parampublicRocketMQLocalTransactionStatecheckLocalTransaction(Message//1.finalJSONObjectjsonObject=JSON.parseObject(newString((byte[])AccountChangeEventaccountChangeEvent//2.查詢de_duplicationintisExistTx=return}elsereturn6.完善ControllerpublicclassAccountInfoController{privateAccountInfoServicepublicclassAccountInfoController{privateAccountInfoServicepublicStringtransfer(){return"轉(zhuǎn)賬成功實現(xiàn)數(shù)據(jù)訪問層,和bank1實現(xiàn)業(yè)務(wù)層功能,增加賬號余額,注意這里使用了交易記錄去重表(de_duplicatio)控制@paramvoidupdateAccountBalance(AccountChangeEventpublicclassAccountInfoServiceImplimplementsAccountInfoService@Transactional(isolation=publicvoidupdateAccountBalance(AccountChangeEventaccountChange){intisExistTx=accountInfoDao.isExistTx(accountChange.getTxNo());if(isExistTx==0){3.實現(xiàn)RocketMQ事務(wù)消息監(jiān)聽器,5.3.4bank1和bank2bank1執(zhí)行本地事務(wù)失敗,則5.3.4bank1和bank2bank1執(zhí)行本地事務(wù)失敗,則bank2為基于消息執(zhí)行的異步操作,避免了分布式事務(wù)中的同步阻塞操作的影響,并實現(xiàn)了兩個服務(wù)的解耦。privateAccountInfoServicepublicvoidonMessage(StringprojectStr){System.out.println("開始消費消息:"+projectStr);AccountChangeEventaccountChangeEvent=在滿標(biāo)放款業(yè)務(wù)中(上圖紅框部分在滿標(biāo)放款業(yè)務(wù)中(上圖紅框部分),交易中心修改標(biāo)的狀態(tài)為“還款中”劃和應(yīng)收明細(xì)。兩者為原子性綁定,即:標(biāo)的狀態(tài)修改成功,就必須生成還款計劃和應(yīng)收明細(xì)。由于涉及到兩個獨立的微服務(wù),這里就存在分布式事務(wù)問題。業(yè)務(wù)對強一致性要求較低,因此我們可以采用RocetMQ可靠消息實現(xiàn)最終一致性這個解決方案。1.檢查pom.xml1.檢查pom.xml<artifactId>rocketmq-spring-boot-2.檢查Apollo中交易中心項目的micro_ducer.group=3.新建P2pTransactionProducerpublicv
溫馨提示
- 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)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中國變速箱第一軸市場調(diào)查研究報告
- 2025年中國兩用拉力器市場調(diào)查研究報告
- 2025至2031年中國閉路監(jiān)控器材行業(yè)投資前景及策略咨詢研究報告
- 2025年聚氨酯耐用油底漆項目可行性研究報告
- 2025年石油公司油票管理系統(tǒng)項目可行性研究報告
- 2025年燃?xì)獬瑝呵袛嚅y項目可行性研究報告
- 2025年橫梁總成項目可行性研究報告
- 惠州2025年廣東惠州龍門縣總醫(yī)院第一批招聘編外人員25人筆試歷年參考題庫附帶答案詳解
- 2025年平紋桃皮絨面料項目可行性研究報告
- 2025年沖壓模具項目可行性研究報告
- 掛靠免責(zé)協(xié)議書范本
- 2024年浙江省五校聯(lián)盟高考地理聯(lián)考試卷(3月份)
- 在線心理健康咨詢行業(yè)現(xiàn)狀分析及未來三至五年行業(yè)發(fā)展報告
- 電動三輪車購銷合同
- 淋巴瘤的免疫靶向治療
- 炎癥性腸病的自我管理
- 國防動員課件教學(xué)課件
- 《地理信息系統(tǒng)GIS》全套教學(xué)課件
- 技術(shù)序列學(xué)習(xí)地圖(2023年)
- 中國銀行(香港)有限公司招聘筆試真題2023
- 15萬噸水廠安裝工程施工組織設(shè)計方案
評論
0/150
提交評論