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

Java中的分布式事務(wù)Seata詳解

 更新時(shí)間:2023年08月30日 09:20:42   作者:余生海  
這篇文章主要介紹了Java中的分布式事務(wù)Seata詳解,Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù),Seata 將為用戶提供了 AT、TCC、SAGA 和 XA 事務(wù)模式,為用戶打造一站式的分布式解決方案,需要的朋友可以參考下

Seata 是什么?

Seata 是一款開源的分布式事務(wù)解決方案,致力于提供高性能和簡(jiǎn)單易用的分布式事務(wù)服務(wù)。

Seata 將為用戶提供了 AT、TCC、SAGA 和 XA 事務(wù)模式,為用戶打造一站式的分布式解決方案。

AT 模式

前提

  • 基于支持本地 ACID 事務(wù)的關(guān)系型數(shù)據(jù)庫(kù)。
  • Java 應(yīng)用,通過 JDBC 訪問數(shù)據(jù)庫(kù)。

整體機(jī)制

  • 一階段:業(yè)務(wù)數(shù)據(jù)和回滾日志記錄在同一個(gè)本地事務(wù)中提交,釋放本地鎖和連接資源。

  • 二階段:

    • 提交異步化,非??焖俚赝瓿伞?/li>
    • 回滾通過一階段的回滾日志進(jìn)行反向補(bǔ)償。

寫隔離

  • 一階段本地事務(wù)提交前,需要確保先拿到全局鎖。
  • 拿不到全局鎖,不能提交本地事務(wù)。
  • 拿全局鎖的嘗試被限制在一定范圍內(nèi),超出范圍將放棄,并回滾本地事務(wù),釋放本地鎖。

以一個(gè)示例來說明:

兩個(gè)全局事務(wù) tx1 和 tx2,分別對(duì) a 表的 m 字段進(jìn)行更新操作,m 的初始值 1000。

tx1 先開始,開啟本地事務(wù),拿到本地鎖,更新操作 m = 1000 - 100 = 900。本地事務(wù)提交前,先拿到該記錄的全局鎖,本地提交釋放本地鎖。 tx2 后開始,開啟本地事務(wù),拿到本地鎖,更新操作 m = 900 - 100 = 800。本地事務(wù)提交前,嘗試拿該記錄的全局鎖,tx1 全局提交前,該記錄的全局鎖被 tx1 持有,tx2 需要重試等待全局鎖。

在這里插入圖片描述

tx1 二階段全局提交,釋放全局鎖。tx2 拿到全局鎖提交本地事務(wù)。

xxx

如果 tx1 的二階段全局回滾,則 tx1 需要重新獲取該數(shù)據(jù)的本地鎖,進(jìn)行反向補(bǔ)償?shù)母虏僮?,?shí)現(xiàn)分支的回滾。

此時(shí),如果 tx2 仍在等待該數(shù)據(jù)的全局鎖,同時(shí)持有本地鎖,則 tx1 的分支回滾會(huì)失敗。分支的回滾會(huì)一直重試,直到 tx2 的全局鎖等鎖超時(shí),放棄全局鎖并回滾本地事務(wù)釋放本地鎖,tx1 的分支回滾最終成功。

因?yàn)檎麄€(gè)過程全局鎖在 tx1 結(jié)束前一直是被 tx1 持有的,所以不會(huì)發(fā)生臟寫的問題。

讀隔離

在數(shù)據(jù)庫(kù)本地事務(wù)隔離級(jí)別讀已提交(Read Committed)或以上的基礎(chǔ)上,Seata(AT 模式)的默認(rèn)全局隔離級(jí)別是讀未提交(Read Uncommitted)。

如果應(yīng)用在特定場(chǎng)景下,必需要求全局的讀已提交,目前 Seata 的方式是通過 SELECT FOR UPDATE 語句的代理。

在這里插入圖片描述

SELECT FOR UPDATE 語句的執(zhí)行會(huì)申請(qǐng)全局鎖,如果全局鎖被其他事務(wù)持有,則釋放本地鎖(回滾 SELECT FOR UPDATE 語句的本地執(zhí)行)并重試。這個(gè)過程中,查詢是被 block 住的,直到全局鎖拿到,即讀取的相關(guān)數(shù)據(jù)是已提交的,才返回。

出于總體性能上的考慮,Seata 目前的方案并沒有對(duì)所有 SELECT 語句都進(jìn)行代理,僅針對(duì) FOR UPDATE 的 SELECT 語句。

工作機(jī)制

以一個(gè)示例來說明整個(gè) AT 分支的工作過程。

業(yè)務(wù)表: product

FieldTypeKey
idbigint(20)PRI
namevarchar(100)
sincevarchar(100)

AT 分支事務(wù)的業(yè)務(wù)邏輯:

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

一階段

過程:

  • 解析 SQL:得到 SQL 的類型(UPDATE),表(product),條件(where name = ‘TXC’)等相關(guān)的信息。
  • 查詢前鏡像:根據(jù)解析得到的條件信息,生成查詢語句,定位數(shù)據(jù)。
select id, name, since from product where name = 'TXC';

得到前鏡像:

idnamesince
1TXC2014
  • 執(zhí)行業(yè)務(wù) SQL:更新這條記錄的 name 為 ‘GTS’。
  • 查詢后鏡像:根據(jù)前鏡像的結(jié)果,通過主鍵定位數(shù)據(jù)。
select id, name, since from product where id = 1`;

得到后鏡像:

idnamesince
1GTS2014
  • 插入回滾日志:把前后鏡像數(shù)據(jù)以及業(yè)務(wù) SQL 相關(guān)的信息組成一條回滾日志記錄,插入到 UNDO_LOG 表中。
{
	"branchId": 641789253,
	"undoItems": [{
		"afterImage": {
			"rows": [{
				"fields": [{
					"name": "id",
					"type": 4,
					"value": 1
				}, {
					"name": "name",
					"type": 12,
					"value": "GTS"
				}, {
					"name": "since",
					"type": 12,
					"value": "2014"
				}]
			}],
			"tableName": "product"
		},
		"beforeImage": {
			"rows": [{
				"fields": [{
					"name": "id",
					"type": 4,
					"value": 1
				}, {
					"name": "name",
					"type": 12,
					"value": "TXC"
				}, {
					"name": "since",
					"type": 12,
					"value": "2014"
				}]
			}],
			"tableName": "product"
		},
		"sqlType": "UPDATE"
	}],
	"xid": "xid:xxx"
}
  • 提交前,向 TC 注冊(cè)分支:申請(qǐng)product表中,主鍵值等于 1 的記錄的全局鎖。
  • 本地事務(wù)提交:業(yè)務(wù)數(shù)據(jù)的更新和前面步驟中生成的 UNDO LOG 一并提交。
  • 將本地事務(wù)提交的結(jié)果上報(bào)給 TC。

二階段-回滾

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

二階段-提交

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

附錄

回滾日志表

UNDO_LOG Table:不同數(shù)據(jù)庫(kù)在類型上會(huì)略有差別。

以 MySQL 為例:

FieldType
branch_idbigint PK
xidvarchar(100)
contextvarchar(128)
rollback_infolongblob
log_statustinyint
log_createddatetime
log_modifieddatetime

 代碼:

-- 注意此處0.7.0+ 增加字段 context
CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

TCC 模式

回顧總覽中的描述:一個(gè)分布式的全局事務(wù),整體是兩階段提交的模型。

全局事務(wù)是由若干分支事務(wù)組成的,分支事務(wù)要滿足兩階段提交的模型要求,即需要每個(gè)分支事務(wù)都具備自己的:

  • 一階段 prepare 行為
  • 二階段 commit 或 rollback 行為

在這里插入圖片描述

根據(jù)兩階段行為模式的不同,我們將分支事務(wù)劃分為Automatic (Branch) Transaction ModeManual (Branch) Transaction Mode.

AT 模式基于支持本地 ACID 事務(wù)關(guān)系型數(shù)據(jù)庫(kù)

  • 一階段 prepare 行為:在本地事務(wù)中,一并提交業(yè)務(wù)數(shù)據(jù)更新和相應(yīng)回滾日志記錄。
  • 二階段 commit 行為:馬上成功結(jié)束,自動(dòng)異步批量清理回滾日志。
  • 二階段 rollback 行為:通過回滾日志,自動(dòng)生成補(bǔ)償操作,完成數(shù)據(jù)回滾。

相應(yīng)的,TCC 模式,不依賴于底層數(shù)據(jù)資源的事務(wù)支持:

  • 一階段 prepare 行為:調(diào)用自定義的 prepare 邏輯。
  • 二階段 commit 行為:調(diào)用自定義的 commit 邏輯。
  • 二階段 rollback 行為:調(diào)用自定義的 rollback 邏輯。

所謂 TCC 模式,是指支持把自定義的分支事務(wù)納入到全局事務(wù)的管理中。

Saga 模式

Saga模式是SEATA提供的長(zhǎng)事務(wù)解決方案,在Saga模式中,業(yè)務(wù)流程中每個(gè)參與者都提交本地事務(wù),當(dāng)出現(xiàn)某一個(gè)參與者失敗則補(bǔ)償前面已經(jīng)成功的參與者,一階段正向服務(wù)和二階段補(bǔ)償服務(wù)都由業(yè)務(wù)開發(fā)實(shí)現(xiàn)。

在這里插入圖片描述

理論基礎(chǔ):Hector & Kenneth 發(fā)表論? Sagas (1987)

適用場(chǎng)景:

  • 業(yè)務(wù)流程長(zhǎng)、業(yè)務(wù)流程多
  • 參與者包含其它公司或遺留系統(tǒng)服務(wù),無法提供 TCC 模式要求的三個(gè)接口

優(yōu)勢(shì):

  • 一階段提交本地事務(wù),無鎖,高性能
  • 事件驅(qū)動(dòng)架構(gòu),參與者可異步執(zhí)行,高吞吐
  • 補(bǔ)償服務(wù)易于實(shí)現(xiàn)

缺點(diǎn):

  • 不保證隔離性

 到此這篇關(guān)于Java中的分布式事務(wù)Seata詳解的文章就介紹到這了,更多相關(guān)Java分布式事務(wù)Seata內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java service層獲取HttpServletRequest工具類的方法

    Java service層獲取HttpServletRequest工具類的方法

    今天小編就為大家分享一篇關(guān)于Java service層獲取HttpServletRequest工具類的方法,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • 對(duì)比Java設(shè)計(jì)模式編程中的狀態(tài)模式和策略模式

    對(duì)比Java設(shè)計(jì)模式編程中的狀態(tài)模式和策略模式

    這篇文章主要介紹了Java設(shè)計(jì)模式編程中的狀態(tài)模式和策略模式對(duì)比,文中列舉了兩種模式的相似點(diǎn)和不同點(diǎn),并都舉了代碼的實(shí)例作為參照,需要的朋友可以參考下
    2016-04-04
  • JavaMe開發(fā)繪制可自動(dòng)換行文本

    JavaMe開發(fā)繪制可自動(dòng)換行文本

    JavaMe Graphics類中的drawString不支持文本換行,這樣繪制比較長(zhǎng)的字符串時(shí),文本被繪制在同一行,超過屏幕部分的字符串被截?cái)嗔?。如何使繪制的文本能自動(dòng)換行呢?
    2015-09-09
  • Java Socket通信介紹及可能遇到的問題解決

    Java Socket通信介紹及可能遇到的問題解決

    最近在學(xué)習(xí)Java中的Socket通信,所以下面這篇文章主要給大家介紹了關(guān)于Java Socket通信介紹及可能遇到問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起看看吧。
    2017-10-10
  • SpringBoot中封裝Cors自動(dòng)配置方式

    SpringBoot中封裝Cors自動(dòng)配置方式

    這篇文章主要介紹了SpringBoot中封裝Cors自動(dòng)配置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-03-03
  • Spring實(shí)例化bean的方式代碼詳解

    Spring實(shí)例化bean的方式代碼詳解

    這篇文章主要介紹了Spring實(shí)例化bean的方式代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下
    2018-01-01
  • Java基于NIO實(shí)現(xiàn)聊天室功能

    Java基于NIO實(shí)現(xiàn)聊天室功能

    這篇文章主要為大家詳細(xì)介紹了Java基于NIO實(shí)現(xiàn)聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Springboot Session共享實(shí)現(xiàn)原理及代碼實(shí)例

    Springboot Session共享實(shí)現(xiàn)原理及代碼實(shí)例

    這篇文章主要介紹了Springboot Session共享實(shí)現(xiàn)原理及代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java(JDK/Tomcat/Maven)運(yùn)行環(huán)境配置及工具(idea/eclipse)安裝詳細(xì)教程

    Java(JDK/Tomcat/Maven)運(yùn)行環(huán)境配置及工具(idea/eclipse)安裝詳細(xì)教程

    這篇文章主要介紹了Java(JDK/Tomcat/Maven)運(yùn)行環(huán)境配置及工具(idea/eclipse)安裝,本文給大家介紹的非常想詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • java實(shí)現(xiàn)在一張大圖片上添加小圖及文字

    java實(shí)現(xiàn)在一張大圖片上添加小圖及文字

    這篇文章主要介紹了java實(shí)現(xiàn)在一張大圖上添加小圖及文字,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11

最新評(píng)論

景德镇市| 固安县| 平顺县| 鸡泽县| 东光县| 台山市| 兴山县| 揭东县| 营山县| 商丘市| 乌拉特后旗| 土默特右旗| 武川县| 攀枝花市| 永川市| 磐安县| 剑川县| 上虞市| 刚察县| 库车县| 鲁山县| 平凉市| 大洼县| 霞浦县| 青州市| 岗巴县| 东兴市| 平乐县| 鄂托克前旗| 成安县| 麻栗坡县| 雷山县| 界首市| 兴和县| 永清县| 凤台县| 东乡| 桃源县| 赫章县| 乌兰浩特市| 巫溪县|