Seata源码—1.Seata分布式事务的模式简介

大纲

1.Seata分布式事务框架简介

2.Seata AT模式实现分布式事务的机制

3.Seata AT模式下的写隔离机制

4.Seata AT模式下的读隔离机制

5.官网示例说明Seata AT模式的工作机制

6.Seata TCC模式的介绍以及与AT模式区别

7.Seata Saga模式的介绍

8.单服务多个库的分布式事务支持

9.Seata的AT、TCC、Saga三种模式对比

10.基于RocketMQ的可靠消息最终一致性事务

11.Seata官方分布式事务例子

1.Seata分布式事务框架简介

(1)Seata的特色功能

(2)Seata的术语

Seata是一款分布式事务解决方案,为用户提供了AT、TCC、SAGA和XA事务模式,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。

(1)Seata的特色功能

一.微服务框架集成支持

已支持Dubbo、Spring Cloud、Sofa-RPC、Motan和gRPC等RPC框架。

二.AT模式

提供无侵入自动补偿的事务模式,目前已支持MySQL、Oracle、PostgreSQL、TiDB和MariaDB。

三.TCC模式

支持TCC模式并可与AT混用,灵活度更高。

四.SAGA模式

为长事务提供的解决方案,提供编排式与注解式。

五.XA模式

支持已实现XA接口的数据库的XA模式,目前已支持MySQL、Oracle、TiDB和MariaDB。

六.高可用

支持计算分离集群模式,水平扩展能力强的数据库和Redis存储模式。

(2)Seata的术语

一.TC(Transaction Coordinator)—事务协调者

用来维护全局和分支事务的状态,驱动全局事务提交或回滚。

二.TM(Transaction Manager)—事务管理器

用来定义全局事务的范围:开始全局事务、提交或回滚全局事务。

三.RM(Resource Manager)—资源管理器

用来管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

2.Seata AT模式实现分布式事务的机制

(1)前提

(2)整体机制

(1)前提

一.基于支持本地ACID事务的关系型数据库

二.Java应用 + 通过JDBC访问数据库

(2)整体机制

两阶段提交协议的演变:

一阶段:首先业务数据和回滚日志记录在同一个本地事务中提交,然后释放本地锁和连接资源。

二阶段:提交异步化,非常快速地完成,回滚通过一阶段的回滚日志进行反向补偿。

3.Seata AT模式下的写隔离机制

(1)Seata在AT模式下的写隔离机制

(2)Seata在AT模式下的写隔离例子

(3)Seata AT模式写隔离下的补偿执行

(4)为什么Seata AT模式要设计写隔离机制

(1)Seata在AT模式下的写隔离机制

一阶段本地事务提交前,需要确保先拿到全局锁。如果拿不到全局锁,就不能提交本地事务。拿全局锁的尝试被限制在一定时间范围内,超出时间范围将被放弃,并回滚本地事务,释放本地锁。

(2)Seata在AT模式下的写隔离例子

以一个示例来说明:两个全局事务tx1和tx2,分别对m字段进行更新操作,m的初始值是1000。

tx1先开始,开启本地事务,拿到本地锁,更新操作m=1000-100=900。本地事务提交前,先拿到该记录的全局锁 ,本地事务提交后释放本地锁。

tx2后开始,开启本地事务,拿到本地锁,更新操作m=900-100=800。本地事务提交前,尝试拿该记录的全局锁。

tx1全局提交前,该记录的全局锁被tx1持有,tx2需要重试等待获取全局锁。tx1二阶段全局提交,释放全局锁。tx2拿到全局锁后,提交其本地事务。

(3)Seata AT模式写隔离下的补偿执行

如果tx1的二阶段全局回滚,则tx1需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。

此时如果tx2仍在等待该数据的全局锁,同时持有本地锁,则tx1的分支回滚会失败,tx1的分支回滚会一直重试,直到tx2的全局锁等锁超时,需要放弃全局锁 + 回滚本地事务 + 释放本地锁,此时tx1的分支回滚才能最终成功。

(4)为什么Seata AT模式要设计写隔离机制

由于整个过程全局锁在tx1结束前一直是被tx1持有的,所以写隔离机制可以保证不会发生脏写的问题。

4.Seata AT模式下的读隔离机制

(1)Seata AT模式的读隔离机制介绍

(2)Seata AT模式的读隔离机制实现

(1)Seata AT模式的读隔离机制介绍

在数据库本地事务隔离级别读已提交(Read Committed)或以上的基础上,Seata AT模式的默认全局隔离级别是读未提交(Read Uncommitted)。

如果应用在特定场景下,必需要求全局的读已提交,目前Seata的方式是通过SELECT FOR UPDATE语句的代理来实现。

(2)Seata AT模式的读隔离机制实现

SELECT FOR UPDATE语句的执行会申请全局锁。如果全局锁被其他事务持有,则释放本地锁(回滚SELECT FOR UPDATE语句的本地执行)并重试。

在这个过程中,查询是被阻塞住的。直到拿到全局锁,即读取的相关数据是已提交的,才返回。

出于总体性能上的考虑,Seata目前的方案并没有对所有SELECT语句都进行代理,仅针对FOR UPDATE的SELECT语句。

5.官网示例说明Seata AT模式的工作机制

(1)一阶段的工作过程

(2)二阶段——回滚的工作过程

(3)二阶段——提交的工作过程

(4)使用Seata AT模式需要创建回滚日志表

以一个示例来说明整个AT分支的工作过程:

业务表:product

+-------+--------------+-------+
| Field | Type         | Key   |
+-------+--------------+-------+
| id    | bigint(20)   | PRI   |
+-------+--------------+-------+
| name  | varchar(100) |       |
+-------+--------------+-------+
| since | varchar(100) |       |
+-------+--------------+-------+

AT分支事务的业务逻辑:

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

(1)一阶段的工作过程

步骤一:解析SQL得到SQL的类型、表、条件等相关的信息。比如类型是UPDATE、表是product、条件是where name = 'TXC'。

步骤二:查询前镜像。也就是根据解析得到的条件信息,生成查询语句,定位数据。

select id, name, since from product where name = 'TXC';//得到前镜像如下:
+-------+-------+-------+
| id    | name  | since |
+-------+-------+-------+
| 1     | TXC   |  2014 |
+-------+-------+-------+

步骤三:执行业务SQL。更新这条记录的name为'GTS'。

步骤四:查询后镜像。根据前镜像的结果,通过主键定位数据。

select id, name, since from product where id = 1;//得到后镜像如下:
+-------+-------+-------+
| id    | name  | since |
+-------+-------+-------+
| 1     | GTS   |  2014 |
+-------+-------+-------+

步骤五:插入回滚日志。把前后镜像数据以及业务SQL相关的信息组成一条回滚日志记录,插入到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的记录的全局锁。

步骤七:本地事务提交。业务数据的更新和前面步骤中生成的UNDO LOG一并提交。

步骤八:将本地事务提交的结果上报给TC

(2)二阶段——回滚的工作过程

步骤一:收到TC的分支回滚请求,开启一个本地事务执行如下操作。

步骤二:通过XID和Branch ID查找到相应的UNDO LOG记录。

步骤三:拿UNDO LOG中的后镜像与当前数据进行数据校验。如果有不同,说明数据被当前全局事务之外的动作做了修改。这种情况,需要根据配置策略来做处理。

步骤四:根据UNDO LOG中的前镜像和业务SQL信息生成并执行回滚语句。

步骤五:提交本地事务并把执行结果(即分支事务回滚的结果)上报给TC。

(3)二阶段——提交的工作过程

步骤一:收到TC的分支提交请求,把请求放入一个异步任务的队列中,然后马上返回提交成功的结果给TC。

步骤二:异步任务阶段执行分支提交请求,将异步和批量地删除相应UNDO LOG记录。

(4)使用Seata AT模式需要创建回滚日志表

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;

6.Seata TCC模式的介绍以及与AT模式区别

(1)Seata TCC模式的介绍

(2)TCC模式与AT模式的区别

(1)Seata TCC模式的介绍

TCC = Try + Commit + Cancel。一个分布式的全局事务,整体是两阶段提交的模型。全局事务是由若干分支事务组成,分支事务要满足两阶段提交的模型要求。

即需要每个分支事务都具备自己的:一阶段Prepare行为(Try行为),二阶段Commit或Rollback行为(Commit + Cancel行为)。

(2)TCC模式与AT模式的区别

所谓TCC模式,是指支持把自定义的分支事务纳入到全局事务的管理中。其实一开始,Seata只有TCC模式,后来才加入AT模式。但TCC模式太麻烦了,每个功能都需要实现三套SQL逻辑,AT模式其实是对TCC模式的简化。

AT模式基于支持本地ACID事务的关系型数据库:

一阶段Prepare行为:在本地事务中,一起提交业务数据更新和相应回滚日志记录。

二阶段Commit行为:马上成功结束,自动 + 异步 + 批量清理回滚日志。

二阶段Rollback行为:通过回滚日志,自动生成补偿操作,完成数据回滚。

TCC模式则不依赖于底层数据资源的事务支持:

一阶段Prepare行为:调用自定义Prepare逻辑。

二阶段Commit行为:调用自定义Commit逻辑。

二阶段Rollback行为:调用自定义Rollback逻辑。

7.Seata Saga模式的介绍

Saga模式是Seata提供的长事务解决方案。在Saga模式中,业务流程中每个参与者都提交本地事务,当出现某一个参与者失败则补偿前面已经成功的参与者。一阶段正向服务和二阶段补偿服务都由业务开发实现。

Saga模式的正向服务可以理解成是TCC模式的Try阶段 + Commit阶段,逆向补偿服务可以理解成是TCC模式的Cancel阶段。

一.适用场景

场景一:业务流程长、业务流程多

场景二:无法提供TCC模式要求的三个接口

比如参与者包含其它公司,或者遗留的老系统服务。

二.优势

一阶段提交本地事务,无锁 + 高性能。

事件驱动架构,参与者可异步执行,高吞吐。

补偿服务易于实现。

三.缺点

不保证隔离性,写不隔离。

8.单服务多个库的分布式事务支持

单个服务对接了多个库。比如该服务处理一个请求时,需要更新多个数据库。分支事务是分布在多个数据库上的,并不是分布在多个服务上的。Seata也天然支持这种情况下的分布式事务。

每个数据库上的事务也都会到Seata上注册一个分支事务。注册之后,各个分支事务也和Seata的AT模式一样:申请本地锁 + 生成undo log + 申请全局锁 + 在其对应数据库上提交增删改。

9.Seata的AT、TCC、Saga三种模式对比

AT模式适用于底层存储都相同的情况,比如都是MySQL等。一般选用AT模式即可,简单方便。

TCC模式适用于底层存储是异构的情况,比如MySQL + Redis + ES等。TCC模式一般在try阶段写入一条数据并标记未生效状态,然后在commit阶段才正式标记为正常生效状态。

TCC模式最大的优点就是很灵活。即使事务失败了,try阶段写入的数据基本也不会影响线上业务。TCC模式特别适用于异构存储要支持事务的情况。

Saga模式适用于异构系统、长流程、改造成TCC特别复杂繁琐的情况。

10.基于RocketMQ的可靠消息最终一致性事务

同步事务:在Seata的AT、TCC、Saga中选一种。

异步事务:使用RocketMQ的事务机制或者自己实现一套最终一致性事务框架。

11.Seata官方分布式事务例子

https://seata.io/zh-cn/docs/user/quickstart.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/80965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】之音视频编程2:QtAV的使用篇

QtAV 基本播放控制功能实现&#xff08;C & QML&#xff09; QtAV 提供了完整的播放控制 API&#xff0c;支持 播放、暂停、停止、快进快退、截屏 等功能。以下是具体实现方法&#xff1a; 1. C 控制方式 基本播放控制 #include <QtAV> #include <QtAV/AVPlaye…

歌词滚动效果

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><!-- 设置标签页图标 --><link rel"shortcut icon&…

基于大模型的TIA诊疗全流程智能决策系统技术方案

目录 一、多模态数据融合与预处理系统1.1 数据接入模块1.2 数据预处理伪代码二、TIA智能预测模型系统2.1 模型训练流程2.2 混合模型架构伪代码三、术中智能监测系统3.1 实时监测流程3.2 实时预测伪代码四、智能诊疗决策系统4.1 手术方案推荐流程4.2 麻醉方案生成伪代码五、预后…

Java 日期解析与格式化:从标准格式到自然语言解析

使用 Java 搭配 Apache Commons Lang3 和 Natty 库&#xff0c;实现灵活高效的日期解析与格式化。 一、背景 将不同格式的日期统一成一个格式。日期格式可能有以下几种类型&#xff1a; 标准格式&#xff1a;2024-02-28、14/05/2022、2002年5月6日非英文月份缩写&#xff1a;…

Room持久化库:从零到一的全面解析与实战

简介 在Android开发中,Room作为官方推荐的数据库持久化库,提供了对SQLite的抽象层,使得数据库操作更加安全、高效且易于维护。 Room通过注解处理器和编译时验证,显著降低了数据库操作的复杂度,同时支持响应式编程模式,使开发者能够轻松实现数据变化的实时监听。对于企业…

MySQL(6)如何删除数据库和表?

在 MySQL 中删除数据库和表是常见的管理操作。下面将详细介绍如何使用 SQL 语句以及图形化工具来删除数据库和表。 步骤一&#xff1a;连接 MySQL 服务器 首先&#xff0c;连接到 MySQL 服务器&#xff0c;可以使用命令行工具 mysql 或图形化工具如 MySQL Workbench。 使用命…

携固态电池、新形态钢壳叠片电池等产品 豪鹏科技将亮相CIBF 2025

携固态电池、新形态钢壳叠片电池等产品 豪鹏科技将亮相CIBF 2025 来源&#xff1a; 电池百人会-电池网 豪鹏科技&#xff08;展位号:14W001&#xff09;将携固态电池、新形态钢壳叠片电池及高安全性钠离子电池等前沿技术产品亮相CIBF 2025&#xff0c;凭借多年的技术积累和产…

React学习———useEffect和useLayoutEffect

useEffect useEffect是React的一个Hook&#xff0c;用于在函数组件中处理副作用。副作用包括数据获取、订阅、手动DOM操作以及其他需要再渲染后执行的操作 基本用法 useEffect(() > {// 副作用逻辑return () > {// 可选的清理函数} }, [依赖数组])第一个参数&#xff…

“天神之眼”计算平台的算力设计(预计500-1000 TOPS)

关于比亚迪“天神之眼”计算平台的算力设计&#xff08;预计500-1000 TOPS&#xff09;&#xff0c;其技术路径和行业意义值得深入探讨。以下从实现方式、技术挑战和行业影响三个维度展开分析&#xff1a; 1. 多芯片互联的技术实现路径 &#xff08;1&#xff09;芯片选型方案…

FPGA: Xilinx Kintex 7实现PCIe接口

在Xilinx Kintex-7系列FPGA上实现PCIe&#xff08;Peripheral Component Interconnect Express&#xff09;接口&#xff0c;通常使用Xilinx提供的7 Series Integrated Block for PCIe IP核&#xff0c;结合Vivado设计流程。以下是实现PCIe接口的详细步骤和关键点&#xff0c;适…

ArcGIS Desktop使用入门(二)常用工具条——图形

系列文章目录 ArcGIS Desktop使用入门&#xff08;一&#xff09;软件初认识 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——标准工具 ArcGIS Desktop使用入门&#xff08;二&#xff09;常用工具条——编辑器 ArcGIS Desktop使用入门&#xff08;二&#x…

JT/T 808 通讯协议及数据格式解析

文章目录 一、引言二、协议数据帧结构三、消息头结构&#xff08;Message Header&#xff09;四、常用消息类型&#xff08;Message ID&#xff09;五、典型消息体结构解析六、数据转义规则七、校验码计算方法八、终端与平台通信流程示意&#xff08;简要&#xff09;九、平台接…

Rust 输出到命令行

Rust 输出到命令行 引言 Rust 是一门系统编程语言&#xff0c;以其高性能、内存安全、并发支持和零成本抽象等特性而闻名。在开发过程中&#xff0c;将 Rust 程序的输出传递到命令行是常见的需求。本文将详细介绍 Rust 输出到命令行的多种方法&#xff0c;帮助读者掌握这一技…

从字符串转换到矩阵快速幂:解决多次转换后的长度问题

引言 在编程竞赛和算法问题中&#xff0c;我们经常会遇到需要对字符串进行多次转换的问题。本文将介绍一个有趣的问题&#xff1a;给定一个字符串和转换规则&#xff0c;计算经过多次转换后字符串的长度。由于直接模拟会导致性能问题&#xff0c;我们将使用矩阵快速幂来高效解…

Vue2 elementUI 二次封装命令式表单弹框组件

需求&#xff1a;封装一个表单弹框组件&#xff0c;弹框和表单是两个组件&#xff0c;表单组件以插槽的形式动态传入弹框组件中。 外部组件使用的方式如下&#xff1a; 直接上代码&#xff1a; MyDialog.vue 弹框组件 <template><el-dialog:titletitle:visible.syn…

React Hooks:从“这什么鬼“到“真香“的奇幻之旅

写在前面:一个让React老手都拍案叫绝的魔法 “等等,函数组件怎么能有状态?!” —— 这是2018年我第一次听说React Hooks时的反应。当时我正在用class组件写一个复杂的表单,生命周期方法乱得像一碗意大利面。直到我看到了这段代码: function Counter() {const [count, s…

论文阅读笔记——双流网络

双流网络论文 视频相比图像包含更多信息&#xff1a;运动信息、时序信息、背景信息等等。 原先处理视频的方法&#xff1a; CNN LSTM&#xff1a;CNN 抽取关键特征&#xff0c;LSTM 做时序逻辑&#xff1b;抽取视频中关键 K 帧输入 CNN 得到图片特征&#xff0c;再输入 LSTM&…

SpringBoot Vue MySQL酒店民宿预订系统源码(支付宝沙箱支付)+代码讲解视频

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

右值引用的学习

传统的C语法中就有引用的语法&#xff0c;而C11中新增了的右值引用语法特性&#xff0c;所以从现在开始我们之前学习的引用就叫做左值引用。无论左值引用还是右值引用&#xff0c;都是给对象取别名。 左值引用和右值引用 在讲之前&#xff0c;我们先来看一下什么是左值和右值…

PHP黑白胶卷底片图转彩图功能 V2025.05.15

关于底片转彩图 传统照片底片是摄影过程中生成的反色图像&#xff0c;为了欣赏照片&#xff0c;需要通过冲印过程将底片转化为正像。而随着数字技术的发展&#xff0c;我们现在可以使用数字工具不仅将底片转为正像&#xff0c;还可以添加色彩&#xff0c;重现照片原本的色彩效…