溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

分布式事務(wù)的含義

發(fā)布時(shí)間:2021-06-15 17:45:09 來(lái)源:億速云 閱讀:122 作者:chen 欄目:web開發(fā)

本篇內(nèi)容介紹了“分布式事務(wù)的含義”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

事務(wù)

事務(wù)其實(shí)大家應(yīng)該不陌生,尤其是對(duì)于程序員來(lái)說(shuō),如果你連事務(wù)都沒(méi)聽說(shuō)過(guò),沒(méi)關(guān)系,因?yàn)槟阌龅搅寺斆骱筒胖怯谝惑w的我,事務(wù)其實(shí)就是為了處理多種混合操作,涉及到多方面業(yè)務(wù)的情景

重點(diǎn)是事務(wù)應(yīng)用的場(chǎng)景就是為了解決多種事務(wù)必須要么同時(shí)完成,要么同時(shí)不能完成的場(chǎng)景,也就是做到真正意義上的"同生共死"

嚴(yán)格意義上來(lái)說(shuō)事務(wù)其實(shí)具有原子性、一致性、隔離性和持久性四種特性,也就是大家老生常談的ACID

  • 原子性(Atomicity),可以理解為一個(gè)事務(wù)內(nèi)的所有操作要么都執(zhí)行,要么都不執(zhí)行

  • 一致性(Consistency),可以理解為數(shù)據(jù)是滿足完整性約束的,也就是不會(huì)存在中間狀態(tài)的數(shù)據(jù),比如你賬上有400,我賬上有100,你給我打200塊,此時(shí)你賬上的錢應(yīng)該是200,我賬上的錢應(yīng)該是300,不會(huì)存在我賬上錢加了,你賬上錢沒(méi)扣的中間狀態(tài)

  • 隔離性(Isolation),指的是多個(gè)事務(wù)并發(fā)執(zhí)行的時(shí)候不會(huì)互相干擾,即一個(gè)事務(wù)內(nèi)部的數(shù)據(jù)對(duì)于其他事務(wù)來(lái)說(shuō)是隔離的

  • 持久性(Durability),指的是一個(gè)事務(wù)完成了之后數(shù)據(jù)就被永遠(yuǎn)保存下來(lái),之后的其他操作或故障都不會(huì)對(duì)事務(wù)的結(jié)果產(chǎn)生影響

嚴(yán)格意義上來(lái)說(shuō)事務(wù)其實(shí)具有原子性、一致性、隔離性和持久性四種特性,也就是大家老生常談的ACID

其實(shí)在我們印象中,應(yīng)該對(duì)這個(gè)事務(wù)再熟悉不過(guò)了,大家都知道事務(wù)就是為了使得一些數(shù)據(jù)庫(kù)層面的更新操作要么全部成功,要么全部失敗。

不知道大家學(xué)過(guò)Redis沒(méi)有,如果學(xué)過(guò)Redis的其實(shí)可能會(huì)有疑問(wèn),因?yàn)镽edis的事務(wù)不能保證所有操作要么都執(zhí)行,要么都不執(zhí)行,但是也叫做事務(wù)。Redis其實(shí)在官網(wǎng)就已經(jīng)說(shuō)明白了,官網(wǎng)中告訴大家事務(wù)中的某個(gè)命令失敗了,之后的命令還是會(huì)被處理,Redis不會(huì)停止執(zhí)行命令,也就是意味著不會(huì)回滾

Redis解釋為什么不支持回滾

他們給出的回的就是首先如果命令出錯(cuò)那就是語(yǔ)法的錯(cuò)誤,是屬于個(gè)人的編程錯(cuò)誤,而且這種情況應(yīng)該被檢測(cè)出來(lái),而不是在生產(chǎn)環(huán)境出現(xiàn),于是乎Redis為了速度更快不支持回滾操作

感覺(jué)很有道理的樣子,但是又有點(diǎn)不對(duì)勁

好了,這下大家都知道事務(wù)是啥了,那么我們一起來(lái)看看分布式事務(wù)吧

分布式事務(wù)

剛才說(shuō)的事務(wù)都是屬于單體程序中,單機(jī)中這樣是沒(méi)問(wèn)題的,通過(guò)普通的事務(wù)操作就可以來(lái)解決;當(dāng)我們的系統(tǒng)逐漸變大,日益變強(qiáng)的同時(shí),并發(fā)量和系統(tǒng)都隨之而增加,當(dāng)涉及到多個(gè)系統(tǒng)之間的配合來(lái)完成一個(gè)事務(wù)的時(shí)候,這就比較難辦了,因?yàn)闊o(wú)法直接通過(guò)一個(gè)系統(tǒng)的數(shù)據(jù)庫(kù)來(lái)完成

假設(shè)現(xiàn)在有訂單系統(tǒng)、扣款系統(tǒng)、積分系統(tǒng),這是屬于三個(gè)系統(tǒng),也就是分別在不同的數(shù)據(jù)庫(kù)中,但是我需要保證三個(gè)系統(tǒng)中的服務(wù)要么全部成功、要么全部失敗,其實(shí)像這種設(shè)計(jì)到多個(gè)庫(kù)、多個(gè)系統(tǒng)之間的事務(wù)操作,也就是分布式事務(wù)了

分布式事務(wù)其實(shí)說(shuō)簡(jiǎn)單也簡(jiǎn)單,其實(shí)就是有多個(gè)本地事務(wù)組合而成,對(duì)于分布式事務(wù)而言幾乎滿足不了ACID,其實(shí)對(duì)于單機(jī)事務(wù)大多是情況下也是無(wú)法全部滿足ACID的,否則哪里來(lái)的四種隔離級(jí)別?所以更別說(shuō)分布在不同數(shù)據(jù)庫(kù)、不同系統(tǒng)之間的分布式事務(wù)了

分布式事務(wù)大致可以分為六種,但是其實(shí)這六種又可以按照三種思想來(lái)分類,接下來(lái)一起看看吧

2PC和3PC是一種強(qiáng)一致性事務(wù),不過(guò)還是有數(shù)據(jù)的不一致、阻塞等風(fēng)險(xiǎn),而且只能應(yīng)用在數(shù)據(jù)庫(kù)層面;而TCC是一種補(bǔ)償性事務(wù)的思想,適用的范圍應(yīng)該是比較廣,不過(guò)這種補(bǔ)償性機(jī)制一般對(duì)業(yè)務(wù)的侵入性比較大,每一個(gè)操作都需要實(shí)現(xiàn)對(duì)應(yīng)的三種方法;還有一種思想就是努力實(shí)現(xiàn)最終一致性事務(wù),有本地消息、事務(wù)消息、和最大努力通知這三種方法,都是實(shí)現(xiàn)最終一致性事務(wù),因此適用于于一些對(duì)于時(shí)間不敏感的業(yè)務(wù)

大致了解了這三類,接下來(lái)來(lái)細(xì)細(xì)學(xué)習(xí)每一種吧

  • 2PC二階段提交:準(zhǔn)備階段、提交階段

2PC,又叫做二階段提交,二階段指的是準(zhǔn)備階段和提交兩個(gè)階段

二階段提交屬于一種強(qiáng)一致性的設(shè)計(jì),2PC引入一個(gè)事務(wù)協(xié)調(diào)者的角色來(lái)協(xié)調(diào)管理各參與者的提交和回滾機(jī)制,我們來(lái)看下具體流程

準(zhǔn)備階段協(xié)調(diào)者會(huì)向各個(gè)參與者發(fā)送準(zhǔn)備的命令,這個(gè)準(zhǔn)備其實(shí)就是準(zhǔn)備環(huán)境,可以理解成提交之前的準(zhǔn)備工作

同步的等待所有的資源的響應(yīng)之后,就到了萬(wàn)事俱備,只欠提交的狀態(tài)了

提交階段,提交階段并不一定是提交事務(wù),也有可能是回滾事務(wù),如果第一階段都準(zhǔn)備成功,則第二階段的提交就是提交事務(wù);同理如果第一階段未全部準(zhǔn)備成功,則第二階段提交的就是回滾事務(wù)了。假設(shè)第一階段都準(zhǔn)備成功,則協(xié)調(diào)者向所有參與者發(fā)送提交命令,然后接下來(lái)等待所有參與者都成功之后,返回事務(wù)執(zhí)行成功

分布式事務(wù)的含義

假設(shè)第一階段有部分參與者返回失敗的話,那么協(xié)調(diào)者則會(huì)向所有參與者都發(fā)送回滾事務(wù)的請(qǐng)求,即類似上圖,向全部參與者發(fā)送回滾事務(wù)

說(shuō)到這里其實(shí)有些小伙伴已經(jīng)開始有疑問(wèn)了,我知道了第一階段有失敗的如何處理了,但是如果第二階段出現(xiàn)失敗了咋整呢

其實(shí)這里分了兩種情況,分別是第二階段執(zhí)行的是提交階段、第二階段執(zhí)行的是回滾操作,這兩種情況的處理方式其實(shí)是一樣的,都是屬于不斷地重試,直到重試成功;對(duì)于提交來(lái)說(shuō),可以根據(jù)業(yè)務(wù)場(chǎng)景,執(zhí)行一定次數(shù)的重試之后,嘗試回滾;但是對(duì)于回滾操作,總不能執(zhí)行成功操作吧

所以,如果第二階段是回滾操作有失敗,當(dāng)失敗次數(shù)達(dá)到一定次數(shù)的時(shí)候,最好的方法就是人工介入了

提交流程大致也分析的差不多了,接下來(lái)一起看看細(xì)節(jié)部分,2PC可以看成同步阻塞協(xié)議,同步阻塞的等待所有參與者的第一階段都有響應(yīng)之后,才會(huì)進(jìn)行第二階段的操作;對(duì)于Java基礎(chǔ)很熟悉的小伙伴是不是很快想起來(lái)Java并發(fā)包中的一個(gè)工具類CountDownLatch,以及功能類似的CyclicBarrier,忘記的趕緊回憶下

其實(shí)2PC中對(duì)于這里的同步阻塞是有超時(shí)機(jī)制的,協(xié)調(diào)者等待參與者的響應(yīng)超時(shí)的情況下,會(huì)默認(rèn)失敗,然后協(xié)調(diào)者直接向所有參與者發(fā)起回滾的命令,知道這次事務(wù)失敗

上面這些都是基于參與者的角度來(lái)考慮的,那如果協(xié)調(diào)者出問(wèn)題了呢

協(xié)調(diào)者如果是單點(diǎn)的,出現(xiàn)故障之后,可能會(huì)出現(xiàn)一些系統(tǒng)的問(wèn)題,我們從流程的角度分析下:

準(zhǔn)備階段命令未發(fā)出,協(xié)調(diào)者故障,事務(wù)還沒(méi)開始,問(wèn)題不大;

準(zhǔn)備階段命令發(fā)出了,協(xié)調(diào)者故障,事務(wù)開始了,無(wú)論參與者都是成功還是失敗,最終情況都很糟糕,因?yàn)閰⑴c者無(wú)法等到下一步的指令了,也就是卡碟了,不僅事務(wù)無(wú)法執(zhí)行,還會(huì)鎖定一些公用資源而阻塞其它系統(tǒng);準(zhǔn)備階段命令發(fā)出,全部成功,第二階段執(zhí)行提交階段命令發(fā)出,這種情況也是不行的,因?yàn)橐部赡芤驗(yàn)榉謪^(qū)和網(wǎng)絡(luò)阻塞,某些參與者未收到提交命令,理想情況下如果參與者一次性全部收到提交命令,但是參與者有可能提交失敗,這樣還是需要重試,此時(shí)協(xié)調(diào)者掛了,也是不行

準(zhǔn)備階段命令發(fā)出,部分失敗,第二階段回滾命令發(fā)出,其實(shí)和上面情況類似,也是會(huì)出現(xiàn)各式各樣的問(wèn)題

既然單點(diǎn)協(xié)調(diào)者不行,那就來(lái)個(gè)多個(gè)的吧,通過(guò)選舉機(jī)制再選一個(gè)新協(xié)調(diào)者

如果都處于第一階段,其實(shí)都還好,事務(wù)還沒(méi)提交,直接都會(huì)滾就好了;如果處于第二階段,假設(shè)參與者都沒(méi)掛,此時(shí)新協(xié)調(diào)者可以向所有參與者來(lái)進(jìn)一步確認(rèn)他們自身的情況來(lái)推斷下一步該如何操作,如果個(gè)別參與者掛了,就比較尷尬了。比如協(xié)調(diào)者發(fā)送了回滾的命令,此時(shí)第一個(gè)參與者收到了并執(zhí)行了,然后協(xié)調(diào)者和第一個(gè)參與者都掛掉了,此時(shí)其它參與者都沒(méi)收到請(qǐng)求,然后新協(xié)調(diào)者來(lái)了,它詢問(wèn)了其它的參與者都回答OK,但是它不知道其中第一個(gè)參與者掛了,此時(shí)要是按照全部OK來(lái)處理,直接發(fā)送提交命令,就糟糕了,這不是我們想要的結(jié)果

其實(shí)雖然2PC協(xié)議上沒(méi)說(shuō),但是在實(shí)現(xiàn)的時(shí)候我們需要靈活的讓協(xié)調(diào)者將自己發(fā)過(guò)的請(qǐng)求在哪些地方都記一下,也就類似于日志記錄,這樣新的協(xié)調(diào)者來(lái)的時(shí)候就不、知道此時(shí)該不該發(fā)了

即使協(xié)調(diào)者知道自己應(yīng)該發(fā)提交還是回滾請(qǐng)求,但是在參與者也一起掛了的情況下也是沒(méi)用的,因?yàn)閰f(xié)調(diào)者無(wú)法知道參與者在掛之前有沒(méi)有提交事務(wù),其實(shí)這里最靠譜的方法,就是對(duì)每一步都進(jìn)行相應(yīng)的日志記錄,重要的步驟最好還是強(qiáng)綁定日志記錄的,否則操作成功了,日志記錄失敗那也很糟糕,總之就是要考慮各種極端的情況,盡最大努力去做到每個(gè)細(xì)節(jié)都考慮到

2PC是一種盡量保證強(qiáng)一致性的分布式事務(wù),因?yàn)樗峭阶枞?,而同步阻塞就意味著在某些情況下會(huì)出現(xiàn)鎖定資源的情況,而且單點(diǎn)一旦出現(xiàn)故障,就會(huì)造成資源鎖定的情況

以下代碼取自 <<Distributed System: Principles and Paradigms>>

協(xié)調(diào)者:        write START_2PC to local log; //開始事務(wù)     multicast VOTE_REQUEST to all participants; //廣播通知參與者投票     while not all votes have been collected {         wait for any incoming vote;         if timeout { //協(xié)調(diào)者超時(shí)             write GLOBAL_ABORT to local log; //寫日志             multicast GLOBAL_ABORT to all participants; //通知事務(wù)中斷             exit;         }         record vote;     }   //如果所有參與者都o(jì)k     if all participants sent VOTE_COMMIT and coordinator votes COMMIT {         write GLOBAL_COMMIT to local log;         multicast GLOBAL_COMMIT to all participants;     } else {         write GLOBAL_ABORT to local log;         multicast GLOBAL_ABORT to all participants;     }  參與者:      write INIT to local log; //寫日志     wait for VOTE_REQUEST from coordinator;     if timeout { //等待超時(shí)         write VOTE_ABORT to local log;         exit;     }     if participant votes COMMIT {         write VOTE_COMMIT to local log; //記錄自己的決策         send VOTE_COMMIT to coordinator; wait for DECISION from coordinator;         if timeout {             multicast DECISION_REQUEST to other participants; //超時(shí)通知             wait until DECISION is received;  /* remain blocked*/             write DECISION to local log;         }         if DECISION == GLOBAL_COMMIT             write GLOBAL_COMMIT to local log;         else if DECISION == GLOBAL_ABORT             write GLOBAL_ABORT to local log;     } else {         write VOTE_ABORT to local log;         send VOTE_ABORT to coordinator;     } 每個(gè)參與者維護(hù)一個(gè)線程處理其它參與者的DECISION_REQUEST請(qǐng)求:      while true {         wait until any incoming DECISION_REQUEST is received;         read most recently recorded STATE from the local log;         if STATE == GLOBAL_COMMIT             send GLOBAL_COMMIT to requesting participant;         else if STATE == INIT or STATE == GLOBAL_ABORT;             send GLOBAL_ABORT to requesting participant;         else             skip;  /* participant remains blocked */     }
  • 3PC三階段提交:準(zhǔn)備階段、預(yù)提交階段、提交階段

3PC其實(shí)就是2PC的升級(jí)版,相比于2PC,參與者也引入了超時(shí)機(jī)制,并且還新增了一個(gè)階段使得參與者可以利用這一階段來(lái)統(tǒng)一各自的狀態(tài)

3PC分為三個(gè)階段:準(zhǔn)備階段、預(yù)提交階段、提交階段。看起來(lái)更像是把2PC中的提交階段分為了預(yù)提交和提交的兩個(gè)階段,  但是這里的準(zhǔn)備階段其實(shí)就是詢問(wèn)參與者的自身狀況,就是問(wèn)你現(xiàn)在的狀況如何,負(fù)載是不是超載,還可以再接受新的任務(wù)嗎

而預(yù)提交階段其實(shí)就是類似于2PC的準(zhǔn)備階段,就是除了事務(wù)的提交該做的都做了,就是之前的準(zhǔn)備工作,但是在3PC中叫做預(yù)提交階段

分布式事務(wù)的含義

3PC是首先準(zhǔn)備階段并不會(huì)直接執(zhí)行事務(wù),而是先去詢問(wèn)此時(shí)的參與者是否有條件可以執(zhí)行這個(gè)事務(wù),因此不會(huì)直接鎖住資源,而預(yù)提交階段的引入則是為了起到了一個(gè)統(tǒng)狀態(tài)的作用,在預(yù)處理階段表面所有參與者都已經(jīng)回應(yīng)了

其實(shí)這也多引入了一個(gè)階段,因此性能會(huì)差一些,而且絕大部分的情況下資源也都是沒(méi)問(wèn)題的,也就是可用的,這樣等于每次明知可用但是還是得詢問(wèn)一次

當(dāng)然,這其中哪一個(gè)階段的參與者返回失敗都會(huì)宣布事務(wù)失敗,這個(gè)2PC也是一樣的,當(dāng)然到最后的提交階段和2PC一樣都是只要是提交請(qǐng)求也就只能通過(guò)不斷的重試咯

我們上面說(shuō)過(guò)2PC是同步阻塞的,協(xié)調(diào)者掛在了提交請(qǐng)求還未發(fā)出去的時(shí)候是最尷尬的,所有參與者都已經(jīng)鎖定了資源并且阻塞的等待著,于是引入了超時(shí)機(jī)制,參與者則不用直接干干的等著了,如果是等待提交命令超時(shí),那么參與者就會(huì)提交事務(wù)了,因?yàn)榈搅诉@一階段大概率都是提交的,如果是等待預(yù)提交超時(shí),接下來(lái)也沒(méi)啥影響

這里其實(shí)有一個(gè)問(wèn)題,然后超時(shí)機(jī)制會(huì)帶來(lái)數(shù)據(jù)不一致的問(wèn)題,就是在等待提交命令的時(shí)候超時(shí),那么參與者自動(dòng)提交事務(wù)了,但是呢,也可能執(zhí)行的是回滾機(jī)制,這樣一來(lái)數(shù)據(jù)便出現(xiàn)了不一致了

3PC的引入是為了解決提交階段2PC協(xié)調(diào)者和其中的部分參與者都掛了的情況下,然后之后的新選舉的協(xié)調(diào)者不知道當(dāng)前應(yīng)該是該提交還是回滾的問(wèn)題,新協(xié)調(diào)者來(lái)的時(shí)候發(fā)現(xiàn)有一個(gè)參與者處于預(yù)提交或者提交階段,那么表明所以參與者都已經(jīng)經(jīng)過(guò)確認(rèn)了,所以此時(shí)執(zhí)行的就是提交命令了

3PC就是通過(guò)引入預(yù)提交階段來(lái)是的參與者之間的狀態(tài)得到真正的統(tǒng)一,也就是留了一個(gè)階段讓大家都同步,但是這也是只能讓協(xié)調(diào)者知道如何做,并不能保證這樣做一定是對(duì)的,這其實(shí)和上面的2PC的分析一直,因?yàn)閽炝说膮⑴c者到底有沒(méi)有執(zhí)行事務(wù)是無(wú)法斷定的,所以說(shuō)呢,3PC通過(guò)預(yù)提交階段可以減少故障時(shí)候的復(fù)雜性,但是并不能保證數(shù)據(jù)真正的一致,處理掛了的那個(gè)參與者也恢復(fù)了

一句話總結(jié):3PC相比于2PC做了一定的參與者超時(shí)機(jī)制的改進(jìn),并且增加了預(yù)提交階段,可以使故障恢復(fù)之后的協(xié)調(diào)者的決策復(fù)雜度降低,但整體的交互過(guò)程會(huì)變得更長(zhǎng),性能會(huì)有所下降,而且還會(huì)出現(xiàn)數(shù)據(jù)不一致的情況

  • TCC:Try-Confirm-Cancel

TCC屬于業(yè)務(wù)層面的分布式事務(wù),分布式事務(wù)不僅僅包含數(shù)據(jù)庫(kù)層面的操作,還包括業(yè)務(wù)層面的操作,這時(shí)候TCC就要排上用場(chǎng)了

TCC指的就是Try、Confirm、Cancel三個(gè)步驟,Try指的是預(yù)留,指的是資源的預(yù)留和鎖定;Confirm指的就是確認(rèn)操作,這一步其實(shí)就是屬于真正的執(zhí)行了,真正的消耗資源來(lái)進(jìn)行相應(yīng)的業(yè)務(wù)提交操作;Cancel指的是撤銷操作,可以理解為把預(yù)留階段的動(dòng)作銷毀了,就是一個(gè)回滾操作

從思想上來(lái)看,其實(shí)是和2PC、3PC是類似的,都是先試探性的執(zhí)行,先試探性的鎖定資源,如果每一個(gè)參與者都沒(méi)問(wèn)題了,就可以執(zhí)行真正的操作了,提交或者回滾

分布式事務(wù)的含義

舉個(gè)例子:一個(gè)事務(wù)要執(zhí)行A、B、C三個(gè)操作,那么先對(duì)三個(gè)操作執(zhí)行預(yù)留動(dòng)作,如果所有都預(yù)留成功了那么就執(zhí)行確認(rèn)提交操作,如果其中至少有一個(gè)預(yù)留失敗,那就都執(zhí)行撤銷的動(dòng)作

TCC模型其中還有一個(gè)事務(wù)管理者的角色,用來(lái)記錄TCC有關(guān)的全局事務(wù)操作的狀態(tài),并且準(zhǔn)備提交或者回滾事務(wù),其實(shí)這個(gè)是比較容易理解的,難點(diǎn)在于業(yè)務(wù)上的定義

怎么說(shuō)呢,TCC這種是對(duì)業(yè)務(wù)的侵入較大和業(yè)務(wù)緊耦合,需要根據(jù)相應(yīng)的特定的業(yè)務(wù)場(chǎng)景和業(yè)務(wù)邏輯來(lái)設(shè)定的響應(yīng)操作,其實(shí)還有一點(diǎn)需要注意的是,撤銷和確認(rèn)的操作的執(zhí)行的就是需要重試,就是需要保證操作的冪等性

TCC相對(duì)來(lái)說(shuō),適用的范圍應(yīng)該是更廣的,但是這個(gè)是有一個(gè)缺點(diǎn)的,就是這個(gè)和業(yè)務(wù)是耦合的,需要大量的開發(fā),因?yàn)槎际窃跇I(yè)務(wù)上的實(shí)現(xiàn),等同于每個(gè)場(chǎng)景都需要三個(gè)方法來(lái)實(shí)現(xiàn),就是嵌入業(yè)務(wù),所以TCC是可以跨業(yè)務(wù)系統(tǒng)、跨數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)事務(wù)

  • 本地消息表

本地消息表,就是利用了各個(gè)系統(tǒng)的本地事務(wù)來(lái)實(shí)現(xiàn)分布式事務(wù),這個(gè)呢,其實(shí)很簡(jiǎn)單的道理,其實(shí)就是會(huì)有一張存放本地消息的表,一般都是放在數(shù)據(jù)庫(kù)中,然后在執(zhí)行業(yè)務(wù)的時(shí)候,必須把業(yè)務(wù)的真正的執(zhí)行操作和相應(yīng)的這個(gè)操作的消息放入到消息表中這個(gè)操作,存放到同一個(gè)事務(wù)中,就是只要操作成功了,就必須保證該消息也成功的放入到本地的消息表中了

接下來(lái)調(diào)用下一個(gè)操作的時(shí)候,如果下一個(gè)操作調(diào)用成功了,就可以直接把消息的狀態(tài)改成已成功,調(diào)用失敗也沒(méi)有關(guān)系,我們可以寫一個(gè)定時(shí)任務(wù)來(lái)讀取本地的消息表,然后篩選出未執(zhí)行成功的消息再調(diào)用對(duì)應(yīng)的服務(wù),服務(wù)更新成功了,再改變消息的狀態(tài)

其實(shí)這里也是需要重試機(jī)制,重試就得保證對(duì)應(yīng)服務(wù)的方法是冪等的,而且一般重試也會(huì)有最大的次數(shù),超過(guò)最大次數(shù)的時(shí)候可以人工介入

本地消息表實(shí)現(xiàn)的是業(yè)務(wù)的最終一致性,需要能夠容忍數(shù)據(jù)暫時(shí)不一致的情況

  • 消息事務(wù)

其實(shí)消息事務(wù),最典型的就是屬于RocketMQ中的實(shí)現(xiàn)了,而且應(yīng)用的場(chǎng)景也是比較多的

分布式事務(wù)的含義

RocketMQ的機(jī)制就是先給Broker發(fā)送事務(wù)消息,也就是半消息,半消息指的是這個(gè)消息對(duì)消費(fèi)者來(lái)說(shuō)不可見,然后發(fā)送成功后,發(fā)送之后會(huì)繼續(xù)執(zhí)行本地事務(wù)

第二步就是根據(jù)本地事務(wù)的執(zhí)行結(jié)果向Broker發(fā)送Commit和Rollback命令,如果一直不發(fā)送,RocketMQ的發(fā)送方會(huì)提供一個(gè)反查事務(wù)狀態(tài)的接口,用來(lái)反查相應(yīng)的事務(wù)的結(jié)果到底是成功還是回滾

其實(shí)這也就是個(gè)超時(shí)機(jī)制,在一段時(shí)間內(nèi)沒(méi)有收到任何的操作請(qǐng)求,那么Broker就會(huì)通過(guò)相應(yīng)的結(jié)果查出該事務(wù)是否成功執(zhí)行呢,是Commit還是Rollback

如果是Commit,則broker就會(huì)發(fā)送這個(gè)消息到訂閱方,然后再做對(duì)應(yīng)的操作,做完了之后就可以消費(fèi)這個(gè)消息,如果是Rollback則訂閱方即收不到這個(gè)消息,等同于事務(wù)沒(méi)有執(zhí)行過(guò)

  • 最大努力通知

其實(shí)最大努力通知我個(gè)人認(rèn)為是一種思想,像上面的本地消息表、事務(wù)消息也是屬于最大努力通知類型的

本地消息表會(huì)有后臺(tái)任務(wù)定時(shí)查看未完成的任務(wù)的消息,然后去調(diào)用對(duì)應(yīng)的服務(wù),進(jìn)行多次重試,當(dāng)多次失敗的時(shí)候就需要引入人工,這也是屬于最大努力

事務(wù)消息也是屬于類似,半消息被Commit之后就會(huì)發(fā)送到消費(fèi)端了,如果消費(fèi)端一直不消費(fèi)或者消費(fèi)不了則會(huì)一直重試,如果重試次數(shù)達(dá)到一定數(shù)量,該消息變回進(jìn)入到私信隊(duì)列,也是屬于盡最大努力通知吧

這應(yīng)該是屬于一種思想,盡最大努力的達(dá)到事務(wù)的最終一致,適用于對(duì)時(shí)間不敏感的業(yè)務(wù)場(chǎng)景

“分布式事務(wù)的含義”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI