最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文搞明白Java?Spring?Boot分布式事務(wù)解決方案

 更新時間:2022年07月11日 10:17:39   作者:?江南一點雨?  
這篇文章主要介紹了一文搞明白Java?Spring?Boot分布式事務(wù)解決方案,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

前言

分布式事務(wù),咱們前邊也聊過很多次了,網(wǎng)上其實也有不少文章在介紹分布式事務(wù),不過里邊都會涉及到不少專業(yè)名詞,看的大家云里霧里,所以還是有一些小伙伴在微信上問我。

那么今天,我就再來一篇文章,和大家捋一捋這個話題。以下的內(nèi)容主要圍繞阿里的 seata 來和大家解釋。

1. 什么是反向補償

首先,來和大家解釋一個名詞,大家在看分布式事務(wù)相關(guān)資料的時候,經(jīng)常會看到一個名詞:反向補償。啥是反向補償呢?

我舉一個例子:假設(shè)我們現(xiàn)在有三個微服務(wù)分別是 A、B、C,現(xiàn)在在 A 服務(wù)中分別調(diào)用 B 和 C 服務(wù),為了確保 B 和 C 同時成功或者同時失敗,我們需要使用到分布式事務(wù)。但是按照我們之前對本地事務(wù)的理解,B 和 C 中的本地事務(wù),當 B 服務(wù)中的事務(wù)執(zhí)行完畢并且提交之后,現(xiàn)在 C 服務(wù)中的事務(wù)出現(xiàn)異常需要回滾了,但是,B 已經(jīng)提交了還怎么回滾呀?

此時我們所說的回滾其實并不是傳統(tǒng)意義上的,通過 MySQL redo log 日志來回滾的那種,而是通過一條更新 SQL,再把 B 服務(wù)中已經(jīng)更改過的數(shù)據(jù)復(fù)原。

這就是我們所說的反向補償!

2. 基本概念梳理

Seata 中有三個核心概念:

  • TC (Transaction Coordinator) - 事務(wù)協(xié)調(diào)者:維護全局和分支事務(wù)的狀態(tài),驅(qū)動全局事務(wù)提交或回滾。
  • TM (Transaction Manager) - 事務(wù)管理器:定義全局事務(wù)的范圍,開始全局事務(wù)、提交或回滾全局事務(wù)。
  • RM ( Resource Manager ) - 資源管理器:管理分支事務(wù)處理的資源( Resource ),與 TC 交談以注冊分支事務(wù)和報告分支事務(wù)的狀態(tài),并驅(qū)動分支事務(wù)提交或回滾。

其中,TC 為單獨部署的 Server 服務(wù)端,TM 和 RM 為嵌入到應(yīng)用中的 Client 客戶端。

我們來看如下一張圖片:

圖片

這張圖基本上把這個三個概念解釋清楚了。

其實不看這張圖,我們大概也能猜到分布式事務(wù)的實現(xiàn)原理:首先得有一個全局的事務(wù)協(xié)調(diào)者(TC),各個本地事務(wù)(RM)在開始執(zhí)行的時候,或者在執(zhí)行的過程中,及時將自己的狀態(tài)報告給全局事務(wù)協(xié)調(diào)者,這個全局事務(wù)協(xié)調(diào)者知道每一個分支事務(wù)目前的執(zhí)行狀態(tài),當他(TC)發(fā)現(xiàn)所有的本地事務(wù)都執(zhí)行成功的時候,就通知大家一起提交;當他發(fā)現(xiàn)在本次事務(wù)中,有人執(zhí)行失敗的時候,就通知大家一起回滾(當然這個回滾不一定是真的回滾,而是反向補償)。那么一個事務(wù)什么時候開始什么時候結(jié)束呢?也就是事務(wù)的邊界在哪里?seata 中的分布式事務(wù)都是通過 @GlobalTransactional 注解來實現(xiàn)的,換句話說,這個注解該加在哪里?添加該注解的地方其實就是事務(wù)管理器 TM 了。

經(jīng)過上面的介紹,小伙伴們應(yīng)該明白了,其實用 Seata 實現(xiàn)分布式事務(wù)沒有想象的那么難,原理還是非常 Easy 的。

Seata 中涉及到四種不同的模式,接下來介紹的四種不同模式,其實都是在說當有一個本地事務(wù)失敗的時候,該如何回滾?這就是我們后面要說的四種不同的分布式事務(wù)模式了。

3. 什么是兩階段提交

先來看下面一張圖:

圖片

這張圖里涉及到三個概念:

  • AP:這個不用多說,AP 就是應(yīng)用程序本身。
  • RM:RM 是資源管理器,也就是事務(wù)的參與者,大部分情況下就是指數(shù)據(jù)庫,一個分布式事務(wù)往往涉及到多個 RM。
  • TM: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ù),因此我們只能先讓這三個服務(wù)中的操作各自執(zhí)行,三個服務(wù)中的事務(wù)各自執(zhí)行就是兩階段中的第一階段。

第一階段執(zhí)行完畢后,先不要急著提交,因為三個服務(wù)中有的可能執(zhí)行失敗了,此時需要三個服務(wù)各自把自己一階段的執(zhí)行結(jié)果報告給一個事務(wù)協(xié)調(diào)者,事務(wù)協(xié)調(diào)者收到消息后,如果三個服務(wù)的一階段都執(zhí)行成功了,此時就通知三個事務(wù)分別提交,如果三個服務(wù)中有服務(wù)執(zhí)行失敗了,此時就通知三個事務(wù)分別回滾。

這就是所謂的兩階段提交。

總結(jié)一下:兩階段提交中,事務(wù)分為參與者(例如上圖的各個具體服務(wù))與協(xié)調(diào)者,參與者將操作成敗通知協(xié)調(diào)者,再由協(xié)調(diào)者根據(jù)所有參與者的反饋情報決定各參與者是要提交操作還是中止操作,這里的參與者可以理解為 RM,協(xié)調(diào)者可以理解為 TM。

不過 Seata 中的各個分布式事務(wù)模式,基本都是在二階段提交的基礎(chǔ)上演化出來的,因此并不完全一樣,這點需要小伙伴們注意。

4. AT 模式

AT 模式是一種全自動的事務(wù)回滾模式。

整體上來說,AT 模式是兩階段提交協(xié)議的演變:

  • 一階段:業(yè)務(wù)數(shù)據(jù)和回滾日志記錄在同一個本地事務(wù)中提交,釋放本地鎖和連接資源。
  • 二階段則分兩種情況:2.1 提交異步化,非??焖俚赝瓿伞?.2 回滾通過一階段的回滾日志進行反向補償。

大致上的邏輯就是上面這樣,我們通過一個具體的案例來看看 AT 模式是如何工作的:

假設(shè)有一個業(yè)務(wù)表 product,如下:

圖片

現(xiàn)在我們想做如下一個更新操作:

update?product?set?name?=?'GTS'?where?name?=?'TXC';

步驟如下:

一階段:

  • 解析 SQL:得到 SQL 的類型(UPDATE),表(product),條件(where name = 'TXC')等相關(guān)的信息。
  • 查詢前鏡像:根據(jù)解析得到的條件信息,生成查詢語句,定位數(shù)據(jù)(查找到更新之前的數(shù)據(jù))。
  • 執(zhí)行上面的更新 SQL。
  • 查詢后鏡像:根據(jù)前鏡像的結(jié)果,通過主鍵定位數(shù)據(jù)。
  • 插入回滾日志:把前后鏡像數(shù)據(jù)以及業(yè)務(wù) SQL 相關(guān)的信息組成一條回滾日志記錄,插入到 UNDO_LOG 表中。
  • 提交前,向 TC 注冊分支:申請 product 表中,主鍵值等于 1 的記錄的 全局鎖。
  • 本地事務(wù)提交:業(yè)務(wù)數(shù)據(jù)的更新和前面步驟中生成的 UNDO LOG 一并提交。
  • 將本地事務(wù)提交的結(jié)果上報給 TC。

二階段:

二階段分兩種情況,提交或者回滾。

先來看回滾步驟:

  • 首先收到 TC 的分支回滾請求,開啟一個本地事務(wù),執(zhí)行如下操作。
  • 通過 XID 和 Branch ID 查找到相應(yīng)的 UNDO LOG 記錄(這條記錄中保存了數(shù)據(jù)修改前后對應(yīng)的鏡像)。
  • 數(shù)據(jù)校驗:拿 UNDO LOG 中的后鏡像與當前數(shù)據(jù)進行比較,如果有不同,說明數(shù)據(jù)被當前全局事務(wù)之外的動作做了修改。這種情況,需要根據(jù)配置策略來做處理。
  • 根據(jù) UNDO LOG 中的前鏡像和業(yè)務(wù) SQL 的相關(guān)信息生成并執(zhí)行回滾的語句:update product set name = 'TXC' where id = 1;
  • 提交本地事務(wù)。并把本地事務(wù)的執(zhí)行結(jié)果(即分支事務(wù)回滾的結(jié)果)上報給 TC。

再來看提交步驟:

  • 收到 TC 的分支提交請求,把請求放入一個異步任務(wù)的隊列中,馬上返回提交成功的結(jié)果給 TC。
  • 異步任務(wù)階段的分支提交請求將異步和批量地刪除相應(yīng) UNDO LOG 記錄。

大致上就是這樣一個步驟,思路還是比較清晰的,就是當你要更新一條記錄的時候,系統(tǒng)將這條記錄更新之前和更新之后的內(nèi)容生成一段 JSON 并存入 undo log 表中,將來要回滾的話,就根據(jù) undo log 中的記錄去更新數(shù)據(jù)(反向補償),將來要是不回滾的話,就刪除 undo log 中的記錄。

在整個過程中,開發(fā)者只需要額外創(chuàng)建一張 undo log 表就行了,然后給需要處理全局事務(wù)的地方加上 @GlobalTransactional 注解就行了。

其他的提交呀回滾呀都是全自動的,比較省事。所以如果你項目中選擇了用 seata 來處理分布式事務(wù),那么用 AT 模式的概率還是相當高的。

5. TCC 模式

TCC(Try-Confirm-Cancel) 模式就帶一點手動的感覺了,它也是兩階段,但是和 AT 又不太一樣,我們來看下流程。

官網(wǎng)上有一張 TCC 的流程圖,我們來看下:

圖片

可以看到,TCC 也是分為兩階段:

  • 第一階段是 prepare,在這個階段主要是做資源的檢測和預(yù)留工作,例如銀行轉(zhuǎn)賬,這個階段就先去檢查下用戶的錢夠不夠,不夠就直接拋異常,夠就先給凍結(jié)上。
  • 第二階段是 commit 或 rollback,這個主要是等各個分支事務(wù)的一階段都執(zhí)行完畢,都執(zhí)行完畢后各自將自己的情況報告給 TC,TC 一統(tǒng)計,發(fā)現(xiàn)各個分支事務(wù)都沒有異常,那么就通知大家一起提交;如果 TC 發(fā)現(xiàn)有分支事務(wù)發(fā)生異常了,那么就通知大家回滾。

那么小伙伴可能也發(fā)現(xiàn)了,上面這個流程中,一共涉及到了三個方法,prepare、commit 以及 rollback,這三個方法都完全是用戶自定義的方法,都是需要我們自己來實現(xiàn)的,所以我一開始就說 TCC 是一種手動的模式。

和 AT 相比,大家發(fā)現(xiàn) TCC 這種模式其實是不依賴于底層數(shù)據(jù)庫的事務(wù)支持的,也就是說,哪怕你底層數(shù)據(jù)庫不支持事務(wù)也沒關(guān)系,反正 prepare、commit 以及 rollback 三個方法都是開發(fā)者自己寫的,我們自己將這三個方法對應(yīng)的流程捋順就行了。

6. XA 模式

如果小伙伴們懂得 MySQL 數(shù)據(jù)庫的 XA 事務(wù),那么一下子就懂得 seata 中的 XA 模式是咋回事了。

XA 規(guī)范是 X/Open 組織定義的分布式事務(wù)處理(DTP,Distributed Transaction Processing)標準。

XA 規(guī)范描述了全局的事務(wù)管理器與局部的資源管理器之間的接口。XA規(guī)范的目的是允許的多個資源(如數(shù)據(jù)庫,應(yīng)用服務(wù)器,消息隊列等)在同一事務(wù)中訪問,這樣可以使 ACID 屬性跨越應(yīng)用程序而保持有效。

XA 規(guī)范使用兩階段提交來保證所有資源同時提交或回滾任何特定的事務(wù)。

XA 規(guī)范在上世紀 90 年代初就被提出。目前,幾乎所有主流的數(shù)據(jù)庫都對 XA 規(guī)范提供了支持。

XA 事務(wù)的基礎(chǔ)是兩階段提交協(xié)議。需要有一個事務(wù)協(xié)調(diào)者來保證所有的事務(wù)參與者都完成了準備工作(第一階段)。如果協(xié)調(diào)者收到所有參與者都準備好的消息,就會通知所有的事務(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)者,比如在一個存儲引擎提交時,需要將提交信息寫入二進制日志,這就是一個分布式內(nèi)部 XA 事務(wù),只不過二進制日志的參與者是 MySQL 本身。MySQL 在 XA 事務(wù)中扮演的是一個參與者的角色,而不是協(xié)調(diào)者。

換言之,MySQL 天然的就可以通過 XA 規(guī)范來實現(xiàn)分布式事務(wù),只不過需要借助一些外部應(yīng)用的支持。我們來看下 Seata 中的 XA 模式使用流程。

先來看一張來自官方的圖片:

圖片

可以看到,這也是一個兩階段提交:

  • 一階段:業(yè)務(wù) SQL 操作放在 XA 分支中進行,XA 分支完成后,執(zhí)行 XA prepare,由 RM 對 XA 協(xié)議的支持來保證持久化(即之后任何意外都不會造成無法回滾的情況)。
  • 二階段分兩種情況:提交或者回滾:
  • 分支提交:執(zhí)行 XA 分支的 commit
  • 分支回滾:執(zhí)行 XA 分支的 rollback

和前面兩種模式的區(qū)別在于,XA 模式中的回滾,是正兒八經(jīng)的回滾,是我們傳統(tǒng)意義上所理解的回滾,而不是一種反向補償。

7. Saga 模式

最后再來看看 saga 模式,這種模式應(yīng)用很少,大家作為了解即可。

saga 模式是 seata 提供的長事務(wù)解決方案,然而長事務(wù)是我們在開發(fā)中應(yīng)該避免的,因為效率低并且容易造成死鎖。

這個 saga 模式就有點像流程引擎,開發(fā)者先自己畫一個流程引擎,把整個事務(wù)中涉及到的方法都囊括進來,每一個方法返回什么的時候就是正常的,返回什么就是異常的,正常的就繼續(xù)往下走,異常的就執(zhí)行另一套流程,也就是我們需要提前準備好兩套方法,第一套是各種正常情況的執(zhí)行流程,第二套則是發(fā)生異常之后的執(zhí)行流程,類似下面這樣:

圖片

綠色的都是正常的流程,紅色的則是發(fā)生異常后回滾的流程。回滾中也是一種反向補償。

到此這篇關(guān)于一文搞明白Java Spring Boot分布式事務(wù)解決方案的文章就介紹到這了,更多相關(guān)Spring Boot分布式事務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring配置文件解析之BeanDefinitionReader詳解

    Spring配置文件解析之BeanDefinitionReader詳解

    這篇文章主要介紹了Spring配置文件解析之BeanDefinitionReader詳解,ApplicationContext.xml配置文件解析成Document對象,真正對xml中元素解析的類是在BeanDefinitionDocumentReader的實現(xiàn)類中來完成的,需要的朋友可以參考下
    2024-02-02
  • Springboot中的@ComponentScan注解使用解析

    Springboot中的@ComponentScan注解使用解析

    這篇文章主要介紹了Springboot中的@ComponentScan注解使用解析,@ComponentScan用于類或接口上主要是指定掃描路徑,spring會把指定路徑下帶有指定注解的類注冊到IOC容器中,需要的朋友可以參考下
    2024-01-01
  • Java使用HttpClient詳細示例

    Java使用HttpClient詳細示例

    這篇文章介紹了Java使用HttpClient的詳細示例,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-12-12
  • 深入解析java中的靜態(tài)代理與動態(tài)代理

    深入解析java中的靜態(tài)代理與動態(tài)代理

    本篇文章是對java中的靜態(tài)代理與動態(tài)代理進行了詳細的分析介紹,需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • 詳解SpringBoot如何實現(xiàn)整合微信登錄

    詳解SpringBoot如何實現(xiàn)整合微信登錄

    本文主要介紹了SpringBoot實現(xiàn)整合微信登錄的過程詳解,文中的示例代碼介紹的非常詳細,對我們的學(xué)習過工作有一定的參考價值,需要的朋友可以關(guān)注下
    2021-12-12
  • Java內(nèi)部類的使用教程詳解

    Java內(nèi)部類的使用教程詳解

    在Java中,有些類可以被定義在另一個類的內(nèi)部,我們把在一個類里面定義的類稱為內(nèi)部類。本文主要介紹了Java內(nèi)部類的使用,需要的可以參考一下
    2023-04-04
  • java生成csv文件亂碼的解決方法示例 java導(dǎo)出csv亂碼

    java生成csv文件亂碼的解決方法示例 java導(dǎo)出csv亂碼

    這篇文章主要介紹了java生成csv文件亂碼的解決方法,大家可以直接看下面的示例
    2014-01-01
  • 基于Java Socket實現(xiàn)一個簡易在線聊天功能(一)

    基于Java Socket實現(xiàn)一個簡易在線聊天功能(一)

    這篇文章主要給大家介紹基于Java Socket實現(xiàn)一個簡易在線聊天功能(一),分為客戶端和服務(wù)端兩段代碼,非常具有參考價值,感興趣的朋友一起學(xué)習吧
    2016-05-05
  • jsp如何獲取Session中的值

    jsp如何獲取Session中的值

    這篇文章主要介紹了jsp如何獲取Session中的值,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot統(tǒng)一返回JSON格式實現(xiàn)方法詳解

    SpringBoot統(tǒng)一返回JSON格式實現(xiàn)方法詳解

    這篇文章主要介紹了SpringBoot統(tǒng)一返回JSON格式實現(xiàn)方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習吧
    2023-02-02

最新評論

屯昌县| 商洛市| 榆中县| 安丘市| 福泉市| 五家渠市| 东阿县| 荆门市| 赞皇县| 德惠市| 磐安县| 建宁县| 胶南市| 徐闻县| 济源市| 新建县| 义马市| 大洼县| 南和县| 阿勒泰市| 凌源市| 北川| 拉萨市| 蕉岭县| 邵武市| 朔州市| 香港| 永胜县| 简阳市| 常山县| 隆尧县| 南部县| 会昌县| 彰化市| 新乡市| 木里| 双牌县| 股票| 南江县| 徐汇区| 宜宾县|