<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    SpringCloud分布式事務(wù)

    共 6418字,需瀏覽 13分鐘

     ·

    2021-04-14 17:22

    點擊上方藍(lán)色字體,選擇“標(biāo)星公眾號”

    優(yōu)質(zhì)文章,第一時間送達(dá)

      作者 |  茶底世界

    來源 |  urlify.cn/Bv6Bjy

    76套java從入門到精通實戰(zhàn)課程分享

    在分布式系統(tǒng)中,分布式事務(wù)基本上是繞不開的, 分布式事務(wù)是指事務(wù)的參與者、支持事務(wù)的服務(wù)器、資源服務(wù)器以及事務(wù)管理器分別位于不同的分布式系統(tǒng)的不同節(jié)點之上 。其實就可以簡單理解成在分布式系統(tǒng)中實現(xiàn)事務(wù)。

    一個簡單的例子,電商系統(tǒng)中,下單接口,一般會有扣庫存,扣積分,然后生成訂單。而一般來說,這三個系統(tǒng)都是不同的服務(wù),我們本地不能控制其他服務(wù)的事務(wù),此時如果訂單服務(wù)發(fā)生了錯誤進(jìn)行了回滾,但遠(yuǎn)程的服務(wù),如扣庫存已經(jīng)調(diào)用完成,不能進(jìn)行回滾了。也就是說下單接口的成功與否,不僅取決于本地的 db 操作,而且依賴第三方系統(tǒng)的結(jié)果, 這時候分布式事務(wù)就保證這些操作要么全部成功,要么全部失敗。本質(zhì)上來說,分布式事務(wù)就是為了保證不同數(shù)據(jù)庫的數(shù)據(jù)一致性。

    在講分布式事務(wù)之前,先回顧下本地事務(wù)的知識點。

    一、本地事務(wù)

    嚴(yán)格意義上的事務(wù)實現(xiàn)應(yīng)該是具備原子性( Atomicity )、一致性( Consistency )、隔離性( Isolation )和持久性(Durability),簡稱 ACID。

    • 原子性:一系列操作整體不可拆分,要么都執(zhí)行,要么都不執(zhí)行。

    • 一致性:事務(wù)的執(zhí)行不能破壞數(shù)據(jù)庫數(shù)據(jù)的完整性和一致性,一個事務(wù)在執(zhí)行之前和執(zhí)行之后,數(shù)據(jù)庫都必須處于一致性狀態(tài)

    • 隔離性:事務(wù)之間相互隔離, 指的是多個事務(wù)并發(fā)執(zhí)行的時候不會互相干擾,即一個事務(wù)內(nèi)部的數(shù)據(jù)對于其他事務(wù)來說是隔離的。

    • 持久性:一旦事務(wù)提交,那么它對數(shù)據(jù)庫中的對應(yīng)數(shù)據(jù)的狀態(tài)的變更就會永久保存到數(shù)據(jù)庫中

    通俗意義上事務(wù)就是為了使得一些更新操作要么都成功,要么都失敗。

    隔離性中還有一個隔離級別的概念,總共有4個事務(wù)隔離級別,不同的隔離級別對事務(wù)的處理不同,分別是:未提交讀,已提交讀, 可重復(fù)讀,串行化。這里面又牽扯到三個概念,臟讀、不可重復(fù)讀 ,幻讀,我們先理解這三個概念

    • 臟讀:所謂的臟讀,其實就是讀到了別的事務(wù)回滾前的臟數(shù)據(jù)

    • 不可重復(fù)讀:當(dāng)前事務(wù)先進(jìn)行了一次數(shù)據(jù)讀取,然后再次讀取到的數(shù)據(jù)是別的事務(wù)修改成功的數(shù)據(jù),導(dǎo)致兩次讀取到的數(shù)據(jù)不匹配

    • 幻讀:當(dāng)前事務(wù)讀第一次取到的數(shù)據(jù)比后來讀取到數(shù)據(jù)條目少

    而事務(wù)的隔離級別其實就是如何避免這三種

    • 未提交讀:該隔離級別允許臟讀取,其隔離級別最低,也就是啥都沒避免。

    • 已提交讀 :一個事務(wù)可以讀取已提交的事務(wù),保證了一個事務(wù)不會讀到另一個并行事務(wù)已修改但未提交的數(shù)據(jù)。但是不保證可重復(fù)讀,也就是不保證多次讀取數(shù)據(jù)都相同。

    • 可重復(fù)讀:保證多次讀取一個數(shù)據(jù)時都跟開始讀取的時候一樣, 因此該事務(wù)級別禁止不可重復(fù)讀取和臟讀取,但是有可能出現(xiàn)幻讀數(shù)據(jù)。

    • 串行化:是最嚴(yán)格的事務(wù)隔離級別,它要求所有事務(wù)被串行執(zhí)行,即事務(wù)只能一個接一個的進(jìn)行處理,不能并發(fā)執(zhí)行。該隔離級別能防止臟讀、不可重復(fù)讀、幻讀。

    Mysql默認(rèn)級別是可重復(fù)讀,在編寫代碼時是可以進(jìn)行設(shè)置的。

    而在Spring中七種事務(wù)傳播行為事務(wù)的傳播行為概念:

    • PROPAGATION_REQUIRED:如果當(dāng)前存在事務(wù),則加入該事務(wù),如果當(dāng)前不存在事務(wù),則創(chuàng)建一個新的事務(wù)。

    • PROPAGATION_SUPPORTS:如果存在一個事務(wù),支持當(dāng)前事務(wù)。如果沒有事務(wù),則非事務(wù)的執(zhí)行。

    • PROPAGATION_MANDATORY:如果已經(jīng)存在一個事務(wù),支持當(dāng)前事務(wù)。如果沒有一個活動的事務(wù),則拋出異常。

    • PROPAGATION_REQUIRES_NEW:重新創(chuàng)建一個新的事務(wù),如果當(dāng)前存在事務(wù),延緩當(dāng)前的事務(wù)。

    • PROPAGATION_NOT_SUPPORTED:以非事務(wù)的方式運行,如果當(dāng)前存在事務(wù),暫停當(dāng)前的事務(wù)。

    • PROPAGATION_NEVER:總是非事務(wù)地執(zhí)行,如果存在一個活動事務(wù),則拋出異常。

    • PROPAGATION_NESTED:如果沒有,就新建一個事務(wù);如果有,就在當(dāng)前事務(wù)中嵌套其他事務(wù)。

    這里有個點,Spring的事務(wù)實現(xiàn)是通過代理類實現(xiàn)的,所以同一個對象內(nèi)事務(wù)調(diào)用是默認(rèn)失效的, 默認(rèn)只有在外部調(diào)用事務(wù)才會生效 。

    二、分布式事務(wù)

    回顧完本地事務(wù),讓我們回到分布式事務(wù)的學(xué)習(xí),分布式事務(wù)的實現(xiàn)是建立在很多概念之上的,讓我們先來理解下基礎(chǔ)概念吧。

    2.1 CAP定理

    CAP是分布式當(dāng)中一個非常重要的理論,指的是在一個分布式系統(tǒng)中一致性 (Consistency)、可用性 (Availability)、分區(qū)容錯性(Partition tolerance),三者不可得兼。

    • 一致性:在分布式系統(tǒng)中的所有數(shù)據(jù)備份,在同一時刻是否同樣的值。(等同于所有節(jié)點訪問同一份最新的數(shù)據(jù)副本)

    • 可用性:在集群中一部分節(jié)點故障后,集群整體是否還能響應(yīng)客戶端的讀寫請求。(對數(shù)據(jù)更新具備高可用性)

    • 分區(qū)容錯性:分布式系統(tǒng)在遇到任何網(wǎng)絡(luò)分區(qū)故障的時候,仍然需要能夠保證對外提供滿足一致性和可用性的服務(wù),除非整個網(wǎng)絡(luò)環(huán)境都發(fā)生故障。

    CAP理論是指一個分布式系統(tǒng)不可能同時滿足一致性,可用性和分區(qū)容錯性這個三個基本需求,最多只能同時滿足其中兩項。

    舉個例子:有A、B、C三個服務(wù),都保存一份數(shù)據(jù)是7,而當(dāng)A服務(wù)將這個數(shù)據(jù)改成8,同步到B時,正常,但同步至C時出現(xiàn)了異常,此時C仍然是7,如果此時依舊要保持一致性,那么C服務(wù)就不能可用。

    • 放棄P(CA):如果希望能夠避免系統(tǒng)出現(xiàn)分區(qū)容錯性問題,一種較為簡單的做法就是將所有的數(shù)據(jù)(或者是與事物先相關(guān)的數(shù)據(jù))都放在一個分布式節(jié)點上,這樣雖然無法保證100%系統(tǒng)不會出錯,但至少不會碰到由于網(wǎng)絡(luò)分區(qū)帶來的負(fù)面影響。但是這樣其實就不是分布式系統(tǒng)了,

    • 放棄A(CP):其做法是一旦系統(tǒng)遇到網(wǎng)絡(luò)分區(qū)或其他故障時,那受到影響的服務(wù)需要等待一定的時間,應(yīng)用等待期間系統(tǒng)無法對外提供正常的服務(wù),即不可用

    • 放棄C(AP):這里說的放棄一致性,并不是完全不需要數(shù)據(jù)一致性,是指放棄數(shù)據(jù)的強一致性,保留數(shù)據(jù)的最終一致性。

    大多數(shù)時候我們是選擇AP,也就是選擇放棄一致性,但是這不是絕對的,在一些業(yè)務(wù)中,例如,轉(zhuǎn)賬業(yè)務(wù),是放棄了可用性。

    2.2 BASE理論

    BASE 理論指的是基本可用 Basically Available,軟狀態(tài) Soft State,最終一致性 Eventual Consistency,核心思想是即便無法做到強一致性,但應(yīng)該采用適合的方式保證最終一致性。

    • BA:Basically Available 基本可用,分布式系統(tǒng)在出現(xiàn)故障的時候,允許損失部分可用性,即保證核心可用。

    • S:Soft State 軟狀態(tài),允許系統(tǒng)存在中間狀態(tài),而該中間狀態(tài)不會影響系統(tǒng)整體可用性。

    • E:Eventual Consistency 最終一致性,系統(tǒng)中的所有數(shù)據(jù)副本經(jīng)過一定時間后,最終能夠達(dá)到一致的狀態(tài)。

    這里需要解釋下強一致性,弱一致性和最終一致性。

    強一致性:任何一次讀都能讀到某個數(shù)據(jù)的最近一次寫的數(shù)據(jù)。系統(tǒng)中的所有進(jìn)程,看到的操作順序,都和全局時鐘下的順序一致。簡言之,在任意時刻,所有節(jié)點中的數(shù)據(jù)是一樣的。

    弱一致性: 數(shù)據(jù)更新后,如果能容忍后續(xù)的訪問只能訪問到部分或者全部訪問不到,則是弱一致性。

    最終一致性: 不保證在任意時刻任意節(jié)點上的同一份數(shù)據(jù)都是相同的,但是隨著時間的遷移,不同節(jié)點上的同一份數(shù)據(jù)總是在向趨同的方向變化。簡單說,就是在一段時間后,節(jié)點間的數(shù)據(jù)會最終達(dá)到一致狀態(tài)。

    三、分布式事務(wù)的幾種方案

    上面都是一些理論,用這些理論作為指導(dǎo),分布式事務(wù)有以下一些解決方案

    3.1 2PC/XA

    兩階段提交,顧名思義就是要分兩步提交。存在一個負(fù)責(zé)協(xié)調(diào)各個本地資源管理器的事務(wù)管理器,本地資源管理器一般是由數(shù)據(jù)庫實現(xiàn),事務(wù)管理器在第一階段的時候詢問各個資源管理器是否都就緒?如果收到每個資源的回復(fù)都是 yes,則在第二階段提交事務(wù),如果其中任意一個資源的回復(fù)是 no, 則回滾事務(wù)。

    階段1:提交事務(wù)請求

    事務(wù)管理器向所有本地資源管理器發(fā)起請求,詢問是否是 ready 狀態(tài),所有參與者都將本事務(wù)能否成功的信息反饋發(fā)給協(xié)調(diào)者;

    • 事務(wù)詢問:協(xié)調(diào)者向所有的參與者發(fā)送事務(wù)內(nèi)容,詢問是否可以執(zhí)行事務(wù)提交操作,并開始等待各參與者的響應(yīng)

    • 執(zhí)行事務(wù):各參與者節(jié)點執(zhí)行事務(wù)操作,并將Undo和Redo信息記入事務(wù)日志中

    • 如果參與者成功執(zhí)事務(wù)操作,就反饋給協(xié)調(diào)者Yes響應(yīng),表示事物可以執(zhí)行,如果沒有成功執(zhí)行事務(wù),就反饋給協(xié)調(diào)者No響應(yīng),表示事務(wù)不可以執(zhí)行

    • 二階段提交一些的階段也被稱為投票階段,即各參與者投票票表明是否可以繼續(xù)執(zhí)行接下去的事務(wù)提交操作

    二階段:執(zhí)行事務(wù)提交

    • 假如協(xié)調(diào)者從所有的參與者或得反饋都是Yes響應(yīng),那么就會執(zhí)行事務(wù)提交。

    • 發(fā)送提交請求:協(xié)調(diào)者向所有參與者節(jié)點發(fā)出Commit請求

    • 事務(wù)提交:參與者接受到Commit請求后,會正式執(zhí)行事務(wù)提交操作,并在完成提交之后放棄整個事務(wù)執(zhí)行期間占用的事務(wù)資源

    • 反饋事務(wù)提交結(jié)果:參與者在完成事物提交之后,向協(xié)調(diào)者發(fā)送ACK消息

    • 完成事務(wù):協(xié)調(diào)者接收到所有參與者反饋的ACK消息后,完成事務(wù)

    中斷事務(wù)

    • 假如任何一個參與者向協(xié)調(diào)者反饋了No響應(yīng),或者在等待超時之后,協(xié)調(diào)者尚無法接收到所有參與者的反饋響應(yīng),那么就中斷事務(wù)。

    • 發(fā)送回滾請求:協(xié)調(diào)者向所有參與者節(jié)點發(fā)出Rollback請求

    • 事務(wù)回滾:參與者接收到Rollback請求后,會利用其在階段一種記錄的Undo信息執(zhí)行事物回滾操作,并在完成回滾之后釋放事務(wù)執(zhí)行期間占用的資源。

    • 反饋事務(wù)回滾結(jié)果:參與則在完成事務(wù)回滾之后,向協(xié)調(diào)者發(fā)送ACK消息

    • 中斷事務(wù):協(xié)調(diào)者接收到所有參與者反饋的ACk消息后,完成事務(wù)中斷

    這種解決方案優(yōu)點是實現(xiàn)簡單,缺點也很明顯:

    同步阻塞:當(dāng)參與事務(wù)者存在占用公共資源的情況,其中一個占用了資源,其他事務(wù)參與者就只能阻塞等待資源釋放,處于阻塞狀態(tài)。

    單點故障:一旦事務(wù)管理器出現(xiàn)故障,整個系統(tǒng)不可用

    數(shù)據(jù)不一致:在階段二,如果事務(wù)管理器只發(fā)送了部分 commit 消息,此時網(wǎng)絡(luò)發(fā)生異常,那么只有部分參與者接收到 commit 消息,也就是說只有部分參與者提交了事務(wù),使得系統(tǒng)數(shù)據(jù)不一致。

    不確定性:當(dāng)協(xié)事務(wù)管理器發(fā)送 commit 之后,并且此時只有一個參與者收到了 commit,那么當(dāng)該參與者與事務(wù)管理器同時宕機(jī)之后,重新選舉的事務(wù)管理器無法確定該條消息是否提交成功。

    還有3PC提交,是對2PC提交做了一些改進(jìn)

    • 與兩階段提交不同的是,三階段提交有兩個改動點。引入超時機(jī)制。同時在協(xié)調(diào)者和參與者中都引入超時機(jī)制。在第一階段和第二階段中插入一個準(zhǔn)備階段。保證了在最后提交階段之前各參與節(jié)點的狀態(tài)是一致的。

    • 三階段提交就有CanCommit、PreCommit、DoCommit三個階段。

    3.2 TCC

    TCC 指的是Try - Confirm - Cancel

    • Try 指的是預(yù)留,即資源的預(yù)留和鎖定,注意是預(yù)留。

    • Confirm 指的是確認(rèn)操作,這一步其實就是真正的執(zhí)行了。

    • Cancel 指的是撤銷操作,可以理解為把預(yù)留階段的動作撤銷了。

    TCC 事務(wù)機(jī)制相比于上面介紹的 XA,解決了其幾個缺點:

    1. 解決了協(xié)調(diào)者單點,由主業(yè)務(wù)方發(fā)起并完成這個業(yè)務(wù)活動。業(yè)務(wù)活動管理器也變成多點,引入集群。

    2. 同步阻塞:引入超時,超時后進(jìn)行補償,并且不會鎖定整個資源,將資源轉(zhuǎn)換為業(yè)務(wù)邏輯形式,粒度變小。

    3. 數(shù)據(jù)一致性,有了補償機(jī)制之后,由業(yè)務(wù)活動管理器控制一致性

    TCC(Try Confirm Cancel) Try 階段:嘗試執(zhí)行,完成所有業(yè)務(wù)檢查(一致性), 預(yù)留必須業(yè)務(wù)資源(準(zhǔn)隔離性) Confirm 階段:確認(rèn)執(zhí)行真正執(zhí)行業(yè)務(wù),不作任何業(yè)務(wù)檢查,只使用 Try 階段預(yù)留的業(yè)務(wù)資源,Confirm 操作滿足冪等性。要求具備冪等設(shè)計,Confirm 失敗后需要進(jìn)行重試。Cancel 階段:取消執(zhí)行,釋放 Try 階段預(yù)留的業(yè)務(wù)資源 Cancel 操作滿足冪等性 Cancel 階段的異常和 Confirm 階段異常處理方案基本上一致。

    在 Try 階段,是對業(yè)務(wù)系統(tǒng)進(jìn)行檢查及資源預(yù)覽,比如訂單和存儲操作,需要檢查庫存剩余數(shù)量是否夠用,并進(jìn)行預(yù)留,預(yù)留操作的話就是新建一個可用庫存數(shù)量字段,Try 階段操作是對這個可用庫存數(shù)量進(jìn)行操作。 基于 TCC 實現(xiàn)分布式事務(wù),會將原來只需要一個接口就可以實現(xiàn)的邏輯拆分為 Try、Confirm、Cancel 三個接口,所以代碼實現(xiàn)復(fù)雜度相對較高。

    3.3 本地消息表

    本地消息表其實就是利用了 各系統(tǒng)本地的事務(wù)來實現(xiàn)分布式事務(wù)。

    1. 當(dāng)系統(tǒng) A 被其他系統(tǒng)調(diào)用發(fā)生數(shù)據(jù)庫表更操作,首先會更新數(shù)據(jù)庫的業(yè)務(wù)表,其次會往相同數(shù)據(jù)庫的消息表中插入一條數(shù)據(jù),兩個操作發(fā)生在同一個事務(wù)中

    2. 系統(tǒng) A 的腳本定期輪詢本地消息往 mq 中寫入一條消息,如果消息發(fā)送失敗會進(jìn)行重試

    3. 系統(tǒng) B 消費 mq 中的消息,并處理業(yè)務(wù)邏輯。如果本地事務(wù)處理失敗,會在繼續(xù)消費 mq 中的消息進(jìn)行重試,如果業(yè)務(wù)上的失敗,可以通知系統(tǒng) A 進(jìn)行回滾操作

    本地消息表實現(xiàn)的條件:

    1. 消費者與生成者的接口都要支持冪等

    2. 生產(chǎn)者需要額外的創(chuàng)建消息表

    3. 需要提供補償邏輯,如果消費者業(yè)務(wù)失敗,需要生產(chǎn)者支持回滾操作

    容錯機(jī)制:

    1. 步驟 1 失敗時,事務(wù)直接回滾

    2. 步驟 2、3 寫 mq 與消費 mq 失敗會進(jìn)行重試

    3. 步驟 3 業(yè)務(wù)失敗系統(tǒng) B 向系統(tǒng) A 發(fā)起事務(wù)回滾操作

    此方案的核心是將需要分布式處理的任務(wù)通過消息日志的方式來異步執(zhí)行。消息日志可以存儲到本地文本、數(shù)據(jù)庫或消息隊列,再通過業(yè)務(wù)規(guī)則自動或人工發(fā)起重試。人工重試更多的是應(yīng)用于支付場景,通過對賬系統(tǒng)對事后問題的處理。

    4.4 可靠消息最終一致性

    1. A 系統(tǒng)先向 mq 發(fā)送一條 prepare 消息,如果 prepare 消息發(fā)送失敗,則直接取消操作

    2. 如果消息發(fā)送成功,則執(zhí)行本地事務(wù)

    3. 如果本地事務(wù)執(zhí)行成功,則想 mq 發(fā)送一條 confirm 消息,如果發(fā)送失敗,則發(fā)送回滾消息

    4. B 系統(tǒng)定期消費 mq 中的 confirm 消息,執(zhí)行本地事務(wù),并發(fā)送 ack 消息。如果 B 系統(tǒng)中的本地事務(wù)失敗,會一直不斷重試,如果是業(yè)務(wù)失敗,會向 A 系統(tǒng)發(fā)起回滾請求

    5. mq 會定期輪詢所有 prepared 消息調(diào)用系統(tǒng) A 提供的接口查詢消息的處理情況,如果該 prepare 消息本地事務(wù)處理成功,則重新發(fā)送 confirm 消息,否則直接回滾該消息

    該方案與本地消息最大的不同是去掉了本地消息表,其次本地消息表依賴消息表重試寫入 mq 這一步由本方案中的輪詢 prepare 消息狀態(tài)來重試或者回滾該消息替代。其實現(xiàn)條件與余容錯方案基本一致。目前市面上實現(xiàn)該方案的只有阿里的 RocketMq。

    5.5 盡最大努力通知

    最大努力通知是最簡單的一種柔性事務(wù),適用于一些最終一致性時間敏感度低的業(yè)務(wù),且被動方處理結(jié)果 不影響主動方的處理結(jié)果。

    這個方案的大致意思就是:

    1. 系統(tǒng) A 本地事務(wù)執(zhí)行完之后,發(fā)送個消息到 MQ;

    2. 這里會有個專門消費 MQ 的服務(wù),這個服務(wù)會消費 MQ 并調(diào)用系統(tǒng) B 的接口;

    3. 要是系統(tǒng) B 執(zhí)行成功就 ok 了;要是系統(tǒng) B 執(zhí)行失敗了,那么最大努力通知服務(wù)就定時嘗試重新調(diào)用系統(tǒng) B, 反復(fù) N 次,最后還是不行就放棄。





    鋒哥最新SpringCloud分布式電商秒殺課程發(fā)布

    ??????

    ??長按上方微信二維碼 2 秒





    感謝點贊支持下哈 

    瀏覽 41
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報
    評論
    圖片
    表情
    推薦
    點贊
    評論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    午夜操逼视频 | 91狠狠色丁香婷婷综合久久 | 操骚逼黄色网址 | 久久五月丁香 | 亚洲视频免费完整版在线播放 |