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

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

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

Seata 是什么?

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

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

AT 模式

前提

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

整體機制

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

  • 二階段:

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

寫隔離

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

以一個示例來說明:

兩個全局事務(wù) tx1 和 tx2,分別對 a 表的 m 字段進行更新操作,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ù)的本地鎖,進行反向補償?shù)母虏僮鳎瑢崿F(xiàn)分支的回滾。

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

因為整個過程全局鎖在 tx1 結(jié)束前一直是被 tx1 持有的,所以不會發(fā)生臟寫的問題。

讀隔離

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

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

在這里插入圖片描述

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

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

工作機制

以一個示例來說明整個 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 注冊分支:申請product表中,主鍵值等于 1 的記錄的全局鎖。
  • 本地事務(wù)提交:業(yè)務(wù)數(shù)據(jù)的更新和前面步驟中生成的 UNDO LOG 一并提交。
  • 將本地事務(wù)提交的結(jié)果上報給 TC。

二階段-回滾

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

二階段-提交

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

附錄

回滾日志表

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

以 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 模式

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

全局事務(wù)是由若干分支事務(wù)組成的,分支事務(wù)要滿足兩階段提交的模型要求,即需要每個分支事務(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é)束,自動異步批量清理回滾日志。
  • 二階段 rollback 行為:通過回滾日志,自動生成補償操作,完成數(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提供的長事務(wù)解決方案,在Saga模式中,業(yè)務(wù)流程中每個參與者都提交本地事務(wù),當出現(xiàn)某一個參與者失敗則補償前面已經(jīng)成功的參與者,一階段正向服務(wù)和二階段補償服務(wù)都由業(yè)務(wù)開發(fā)實現(xiàn)。

在這里插入圖片描述

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

適用場景:

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

優(yōu)勢:

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

缺點:

  • 不保證隔離性

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

相關(guān)文章

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

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

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

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

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

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

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

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

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

    SpringBoot中封裝Cors自動配置方式

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

    Spring實例化bean的方式代碼詳解

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

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

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

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

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

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

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

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

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

最新評論

沁水县| 浮山县| 温泉县| 宁河县| 确山县| 唐海县| 兰西县| 公安县| 陕西省| 哈密市| 米泉市| 杂多县| 湘阴县| 湘潭县| 井冈山市| 安平县| 开化县| 如皋市| 锡林郭勒盟| 平乐县| 石台县| 教育| 绵阳市| 濮阳县| 呼图壁县| 五原县| 县级市| 安丘市| 元江| 长沙市| 博野县| 湖南省| 新宾| 武平县| 西昌市| 乌兰浩特市| 晋宁县| 岱山县| 高要市| 镇雄县| 湟源县|