欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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ù)庫。
  • Java 應(yīng)用,通過 JDBC 訪問數(shù)據(jù)庫。

整體機(jī)制

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

  • 二階段:

    • 提交異步化,非??焖俚赝瓿?。
    • 回滾通過一階段的回滾日志進(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ù)庫本地事務(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ù)庫在類型上會(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ù)庫

  • 一階段 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經(jīng)典用法總結(jié)

    Java經(jīng)典用法總結(jié)

    這篇文章主要介紹了Java經(jīng)典用法總結(jié),在本文中,盡量收集一些java最常用的習(xí)慣用法,特別是很難猜到的用法,感興趣的小伙伴們可以參考一下
    2016-02-02
  • Java操作壓縮包解壓過程詳解

    Java操作壓縮包解壓過程詳解

    這篇文章主要介紹了Java操作壓縮包解壓過程,項(xiàng)目開發(fā)中,總會(huì)遇到解壓縮文件的時(shí)候,比如用戶下載多個(gè)文件時(shí),服務(wù)端可以將多個(gè)文件壓縮成一個(gè)文件,用戶上傳資料時(shí),允許上傳壓縮文件,服務(wù)端進(jìn)行解壓讀取每一個(gè)文件,使用場(chǎng)景是很多的,下面來詳細(xì)講解,需要的朋友可以參考下
    2024-10-10
  • 深入理解Java中的構(gòu)造函數(shù)引用和方法引用

    深入理解Java中的構(gòu)造函數(shù)引用和方法引用

    java構(gòu)造函數(shù),也叫構(gòu)造方法,是java中一種特殊的函數(shù)。函數(shù)名與相同,無返回值。方法引用是用來直接訪問類或者實(shí)例的已經(jīng)存在的方法或者構(gòu)造方法。下面我們來詳細(xì)了解一下它們吧
    2019-06-06
  • Java 中HashCode作用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java 中HashCode作用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java 中HashCode作用以及hashcode對(duì)于一個(gè)對(duì)象的重要性,對(duì)java中hashcode的作用相關(guān)知識(shí)感興趣的朋友一起學(xué)習(xí)吧
    2017-05-05
  • Java中接口和抽象類的區(qū)別詳解

    Java中接口和抽象類的區(qū)別詳解

    這篇文章主要介紹了Java中接口和抽象類的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Servlet3.0實(shí)現(xiàn)文件上傳的方法

    Servlet3.0實(shí)現(xiàn)文件上傳的方法

    本篇文章主要介紹了Servlet實(shí)現(xiàn)文件上傳的方法,所謂文件上傳就是將本地的文件發(fā)送到服務(wù)器中保存。有興趣的可以了解一下。
    2017-03-03
  • java爬蟲模擬登陸的實(shí)例詳解

    java爬蟲模擬登陸的實(shí)例詳解

    在本篇文章里小編給大家分享的是一篇關(guān)于java爬蟲模擬登陸的實(shí)例詳解內(nèi)容,有興趣的朋友們可以參考學(xué)習(xí)下。
    2021-01-01
  • Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能詳解

    Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能詳解

    這篇文章主要為大家詳細(xì)介紹了如何使用Java實(shí)現(xiàn)數(shù)據(jù)庫圖片上傳功能,包含從數(shù)據(jù)庫拿圖片傳遞前端渲染,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-03-03
  • swagger的請(qǐng)求參數(shù)不顯示,@Apimodel的坑點(diǎn)及解決

    swagger的請(qǐng)求參數(shù)不顯示,@Apimodel的坑點(diǎn)及解決

    這篇文章主要介紹了swagger的請(qǐng)求參數(shù)不顯示,@Apimodel的坑點(diǎn)及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Spring執(zhí)行流程和Bean的生命周期詳解

    Spring執(zhí)行流程和Bean的生命周期詳解

    這篇文章主要介紹了Spring執(zhí)行流程和Bean的生命周期詳解,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06

最新評(píng)論