分布式事务管理-Seata从入门到精通

一、基本概念

什么是数据库事务?

1、一个操作数据库数据的执行单元
2、到围从开始到结束的多个操作组成
3、事务内的多个操作要么都成功,要么都失败

什么是分布式事务?

1.分布式场景下,完成某一个业务功能可能需要横跨多个服务,操作多个数据库
2.由多个分支事务构成的一个全局事务我们一般叫分布式事务

CAP定理

'C'代表一致性、'A'代表可用性、'P'代表分区容错性

一致性:

        对于给定的客户端,要保证读操作返回的是最近写操作成功的结果。

        对于多个并发请求,要保证每个请求同时读到的数据一定是一致的。

        所以当发生写操作时,分布式系统中,要等到每个节点都写入成功才能确保此次写操作是成功的,否则应当回滚事务。

可用性:

        每一个请求都能在有限时间内收到非错误的响应,但不保证返回的是最新版本的数据。

        非错误的响应指的是这个请求不会超时或返回报错的结果。

        所以顾名思义就是,保证服务是可用的状态。

分区容错性:

        网络分区是指网络中的某些部分因为故障或其他原因无法通信。分区容忍性意味着即使网络分区发生,系统仍然能够继续运行,部分节点之间的通信可能中断,但系统整体仍然可用。

CAP理论指的是三个特性之间,智能同时满足其中两个

CP(一致性 + 分区容忍性):
        特点:系统保证数据的一致性和分区容忍性,但可能牺牲可用性。
        解释:当网络分区发生时,比如就会产生节点之间通信故障,无法及时同步数据,那么系统要优先保证数据的一致性,就可能会拒绝部分请求以避免数据不一致。
        例子:传统的关系型数据库(如 MySQL)通常选择 CP,因为它们强调事务的一致性和持久性。
AP(可用性 + 分区容忍性):
        特点:系统保证可用性和分区容忍性,但可能牺牲一致性。
        解释:当网络分区发生时,比如就会产生节点之间通信故障,那么在AP下,系统会优先保证可用性,可能会返回旧数据或不一致的数据,但确保每个请求都能得到响应。
        例子:NoSQL 数据库(如 Cassandra)通常选择 AP,因为它们强调高可用性和分区容忍性,允许在某些情况下返回旧数据。
CA(一致性 + 可用性):
        特点:系统保证数据的一致性和可用性,但可能牺牲分区容忍性。
        解释:系统在任何情况下都能提供一致的数据,并且每个请求都能得到响应,但当网络分区发生时,系统可能无法继续运行。
        例子:单节点数据库(如单台 MySQL 服务器)通常选择 CA,因为它们在一个节点上运行,不存在网络分区的问题。

CAP实践中的选择

1、虽然理论上是在AP 和 CP中做选择,但并不意味着我们要放弃另一个

2、在实践中选择了AP不代表放弃了C,不一致只是出现在发生网络分区时,网络分区恢复后最终需要保证一致

3、在实践中选择了CP也不代表放弃了A,比如:写入操作只需过半确认,未确认的节点依然能提供读能力(注:你可能会疑问:存在未确认节点,但这些节点任然提供服务,这样不就会造成数据不一致吗。在CP系统重会采用一些机制保证一致性,比如读取操作也需要从超过一半的节点读取数据,然后返回最新的数据。

BASE理论

BASE 是指基本可用(Basically Available)、软状态(Soft state)、最终一致性(Eventualconsistency)基于CAP定理演化而来

        基本可用:分布式系统在出现故障时,允许损失部分可用性,即保证核心可用
        软状态:允许系统存在中间状态[数据不一致],而该中间状态不会影响系统整体正确性
        最终一致性:系统中的所有数据经过一定时间后,最终能够达到一致的状态

刚柔事务

刚性事务:满足ACID理论

柔性事务:满足BASE理论

        柔性事务并不是完全放弃ACID,而是通过放宽一致性要求,借助本地事务来实现最终分布式事务一致性的同时也保证系统的吞吐

二、分布式事务解决方案

常见的分布式解决方案主要分为两大类:

1、较经典的是XA分布式事务协议,XA协议包含二阶段提交(2PC)和三阶段提交(3PC)两种实现

2、基于TCC、本地消息表、MO事务消息等相关的实现

2PC两阶段提交

将事务的处理过程分为两个阶段:准备阶段和提交阶段

事务的发起者称协调者,事务的执行者称参与者。

        在分布式系统里,每个节点都可以知晓自己操作的成功或者失败,却无法知道其他节点操作的成功或失败。当一个事务跨多个节点时,为了保持事务的原子性与一致性,而引入一个协调者来统一掌控所有参与者的操作结果,并指示它们是否要把操作结果进行真正的提交或者回滚(rollback)。

         二阶段提交的算法思路可以概括为:参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。

阶段1-准备阶段

  • 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。
  • 各参与者执行事务操作,将undo和redo信息记入事务日志中(但不提交事务)。
  • 如参与者执行成功,给协调者反馈yes,即可以提交;如执行失败,给协调者反馈no,即不可提交。

阶段2-提交阶段

        如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rollback)消息;否则,发送提交(commit)消息;参与者根据协调者的指令执行提交或者回滚操作,释放所有事务处理过程中使用的锁资源。(注意:必须在最后阶段释放锁资源)

接下来分两种情况分别讨论提交阶段的过程。

情况1,当所有参与者均反馈yes,提交事务:

 情况2,当任何阶段1一个参与者反馈no,中断事务:

2PC的问题

2PC是一个强一致性的同步阻塞协议,事务执⾏过程中需要将所需资源全部锁定,也就是俗称的刚性事务

2PC方案实现起来简单,实际项目中使用比较少,主要因为以下问题:

  • 性能问题
    所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。
  • 可靠性问题
    如果协调者存在单点故障问题,如果协调者出现故障,参与者将一直处于锁定状态。
  • 数据一致性问题
    在阶段2中,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。

3PC三阶段提交 

三阶段提交协议,是二阶段提交协议的改进版本,与二阶段提交不同的是,引入超时机制。同时在协调者和参与者中都引入超时机制(2PC 中只有协调者有超时机制)。

三阶段提交将二阶段的准备阶段拆分为2个阶段,插入了一个preCommit阶段,使得原先在二阶段提交中,参与者在准备之后,由于协调者发生崩溃或错误,而导致参与者处于无法知晓是否提交或者中止的“不确定状态”所产生的可能相当长的延时的问题得以解决。

阶段1:canCommit

协调者向参与者发送canCommit请求,参与者如果可以提交就返回yes响应(参与者不执行事务操作),否则返回no响应:

  • 1、协调者向所有参与者发出包含事务内容的canCommit请求,询问是否可以提交事务,并等待所有参与者答复。
  • 2、参与者收到canCommit请求后,如果认为可以执行事务操作,则反馈yes并进入预备状态,否则反馈no。

阶段2:preCommit

协调者根据阶段1 canCommit参与者的反应情况来决定是否可以基于事务的preCommit操作。根据响应情况,有以下两种可能。

情况1,阶段1所有参与者均反馈yes,参与者预执行事务:

情况2,阶段1任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务:

阶段3:do Commit

该阶段进行真正的事务提交,也可以分为以下两种情况:

情况1:阶段2所有参与者均反馈ack响应,执行真正的事务提交:

 阶段2任何一个参与者反馈no,或者等待超时后协调者尚无法收到所有参与者的反馈,即中断事务:

 注意:进入阶段3后,如果协调者出现问题,或者协调者与参与者网络出现问题,都会导致参与者无法接收到协调者发出的do Commit请求或rollback请求。此时,参与者都会在等待超时之后,继续执行事务提交(默认提交)。

阶段三 只允许成功不允许失败,如果服务器宕机或者停电,因为记录的阶段二的数据,重启服务后在提交事务,所以,到了阶段三,失败了也不进行回滚,只允许成功

TCC

TCC是服务化的二阶段编程模型,其Try、Confirm、Cancel 3个方法均由业务编码实现,基本类似两阶段提交

  • Try操作作为一阶段,负责资源的检查和预留。
  • Confirm操作作为二阶段提交操作,执行真正的业务。(理解为:try成功,就提交事务)
  • Cancel是预留资源的取消。(理解为:try失败,就回滚事务)

本地消息表

本地消息表通过在本地数据库中维护一个消息表,可以记录事务的状态和相关信息,从而实现事务的最终一致性。

在上述执行过程中,只要任何一步执行失败,都要回滚事务,如果事务不可逆,则可能需要人工做一些补偿机制

MQ事务

正常情况——事务主动方发消息

这种情况下,事务主动方服务正常,没有发生故障,发消息流程如下:

1、发送方向 MQ服务端(MQ Server)发送half消息。

2、MQ Server 将消息持久化成功之后,向发送方 ACK 确认消息已经发送成功。

3、发送方开始执行本地事务逻辑。

4、发送方根据本地事务执行结果向 MQ Server 提交二次确认(commit 或是 rollback)。

5、MQ Server 收到 commit 状态则将半消息标记为可投递,订阅方最终将收到该消息;MQ Server 收到 rollback 状态则删除半消息,订阅方将不会接受该消息。

异常情况——事务主动方消息恢复

在断网或者应用重启等异常情况下,图中第4步提交的二次确认超时未到达 MQ Server,此时处理逻辑如下:

  • 5、MQ Server 对该消息发起消息回查。
  • 6、发送方收到消息回查后,需要检查对应消息的本地事务执行的最终结果。
  • 7、发送方根据检查得到的本地事务的最终状态再次提交二次确认
  • 8、MQ Server基于commit / rollback 对消息进行投递或者删除

三、Seata的使用 

Seata支持多种事务模式的实现,包含AT、TCC、SAGA、XA等模式。

本文章以AT模式的使用为例

1、基本概念

  • 全局事务:由多个分支事务组成的一个事务,确保所有分支事务要么全部成功提交,要么全部回滚。
  • 分支事务:全局事务中的一个子事务,对应一个具体的业务操作。
  • TC(Transaction Coordinator):事务协调器,管理全局事务的生命周期,协调各分支事务的提交和回滚。
  • TM(Transaction Manager):事务管理器,负责开启全局事务、提交或回滚全局事务。
  • RM(Resource Manager):资源管理器,管理分支事务,与 TC 交互,报告分支事务的状态,执行分支事务的提交和回滚。

2、工作流程

  1. 开启全局事务

    • TM 向 TC 申请开启一个全局事务,并获得全局事务 ID(XID)。
    • TM 将 XID 传递给业务服务,业务服务在执行业务操作时带上 XID。
  2. 执行业务操作

    • RM 在执行业务 SQL 时,拦截 SQL 并生成对应的 undo_log 记录。
    • undo_log 记录了 SQL 的反向操作,用于在回滚时恢复数据。
    • RM 将 undo_log 记录和业务数据一起提交到数据库。
  3. 提交或回滚全局事务

    • TM 向 TC 发起全局事务的提交或回滚请求。
    • TC 与各个 RM 交互,协调分支事务的提交或回滚。
    • 如果所有分支事务都成功提交,则全局事务提交成功;如果有任何一个分支事务回滚,则全局事务回滚。

3、使用步骤

首先在你的SpringBoot对应需要用Seata的应用中,创建undo_log数据表

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(`branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',`xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',`context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',`log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',`log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',`log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';

依赖的引入

<!--seata-->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId><version>2.2.5.RELEASE</version>
</dependency>

启动SeataServer(TC的位置)

添加Seata配置:在application.yml中添加如下配置

seata:enabled: trueapplication-id: ${spring.application.name}tx-service-group: my_seata_groupenable-auto-data-source-proxy: trueuse-jdk-proxy: falseexcludes-for-auto-proxying: firstClassNameForExclude,secondClassNameForExcludeclient:rm:async-commit-buffer-limit: 1000report-retry-count: 5table-meta-check-enable: falsereport-success-enable: falsesaga-branch-register-enable: falselock:retry-interval: 10retry-times: 30retry-policy-branch-rollback-on-conflict: truetm:degrade-check: falsedegrade-check-period: 2000degrade-check-allow-times: 10commit-retry-count: 5rollback-retry-count: 5undo:data-validation: truelog-serialization: jacksonlog-table: undo_logonly-care-update-columns: truelog:exceptionRate: 100service:vgroup-mapping:my_seata_group: defaultgrouplist:default: localhost:8091enable-degrade: falsedisable-global-transaction: falsetransport:shutdown:wait: 3thread-factory:boss-thread-prefix: NettyBossworker-thread-prefix: NettyServerNIOWorkerserver-executor-thread-prefix: NettyServerBizHandlershare-boss-worker: falseclient-selector-thread-prefix: NettyClientSelectorclient-selector-thread-size: 1client-worker-thread-prefix: NettyClientWorkerThreadworker-thread-size: defaultboss-thread-size: 1type: TCPserver: NIOheartbeat: trueserialization: seatacompressor: noneenable-client-batch-send-request: true

关于配置文件内容参数比较多,我们需要掌握核心部分:

seata_transaction: default:事务分组,前面的seata_transaction可以自定义,通过事务分组很方便找到集群节点信息。
tx-service-group: seata_transaction:指定应用的事务分组,和上面定义的分组前部分保持一致。
default: localhost:8091:服务地址,seata-server服务地址。

接下来在Application中添加@EnableAutoDataSourceProxy注解

在需要进行事务控制的方法上标明@GlobalTransactional注解

到此,方法内部如果发生异常就会触发全局事务回滚了

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

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

相关文章

jmeter入门:脚本录制

1.设置代理。 网络连接-》代理-》手动设置代理. ip&#xff1a; 127.0.0.1&#xff0c; port&#xff1a;8888 2. add thread group 3. add HTTP(s) test script recorder, target controller chooses Test plan-> thread Group 4. click start. then open the browser …

AIGC毕设项目分享:基于RAG的数字人对话系统及其应用

本研究的主要目标是设计并实现一个基于检索增强生成&#xff08;RAG&#xff09;技术的数字人对话系统&#xff0c;旨在提升数字人系统在多轮对话中的上下文管理、情境感知能力以及动态内容生成效果。系统结合了深度学习中的最新大语言模型技术&#xff0c;通过引入RAG框架来增…

ubuntu下route命令详解

buntu下route命令详解 1、显示路由表 route -n2、临时路由设置&#xff0c;重启网卡失效#添加一条路由(发往192.168.62这个网段的全部要经过网关192.168.1.1)route add -net 192.168.62.0 netmask 255.255.255.0 gw 192.168.1.1#删除一条路由 删除的时候不用写网关route del …

华为海思:大小海思的双轮驱动战略分析

华为海思,作为华为旗下的半导体设计部门,近年来在芯片设计领域取得了显著成就,成为了中国乃至全球芯片设计的重要力量。实际上,华为海思并非单一实体,而是由两个主要分支构成:大海思和小海思。这两个分支虽然同属华为海思,但在定位、产品布局以及市场策略上有所不同,共…

【测试】BUG篇——BUG

bug的概念 定义&#xff1a;⼀个计算机bug指在计算机程序中存在的⼀个错误(error)、缺陷(flaw)、疏忽(mistake)或者故障(fault)&#xff0c;这些bug使程序⽆法正确的运⾏。Bug产⽣于程序的源代码或者程序设计阶段的疏忽或者错误。 准确的来说&#xff1a; 当且仅当规格说明&am…

【大数据技术基础 | 实验二】Linux基础:常用基本命令和文件操作

文章目录 一、实验目的二、实验要求三、实验环境四、常用基本命令1、验证cd和pwd命令2、验证ls命令3、验证mkdir命令4、验证cp、mv和rm命令 五、Linux文件操作1、验证touch命令2、验证cat命令3、验证more命令 六、实验心得 一、实验目的 学会linux常用命令(cd,ls,pwd,mkdir,rm…

【Flutter】合并多个流Stream

1.说明 无意间发现了一个好用的库rxdart&#xff0c;它为 Dart 的 Stream 添加了额外的功能。 2.功能 &#xff08;1&#xff09;合并多个流Stream 借助Rx.combineLatest2()合并两个流stream1和stream2。 注意&#xff1a;如果dart文件中同时使用了getx&#xff0c;需要隐…

腾讯云视立方Electron 相关问题

安装相关 trtc-electron-sdk 是否兼容官方 Electron v12.0.1 版本? 兼容的&#xff0c;trtc-electron-sdk 没有特别依赖 elecron 自身的 SDK&#xff0c;所以没有相关的版本依赖。 Electron 下载慢甚至卡住不动&#xff1f; 当开始下载tmp-3320-1-SHASUMS256.txt-6.1.9文件…

【c语言——指针详解(4)】

文章目录 一、回调函数是什么&#xff1f;二、qsort的使⽤1、使⽤qsort函数排序整型数据2、使⽤qsort排序结构数据 三、qsort函数的模拟实现 作者主页 一、回调函数是什么&#xff1f; 回调函数就是⼀个通过函数指针调⽤的函数。 如果你把函数的指针&#xff08;地址&#xf…

【进阶OpenCV】 (12)--人脸检测识别

文章目录 人脸识别一、获取分类器二、代码实现1. 图片预处理2. 加载人脸检测分类器3. 检测人脸4. 标注人脸 总结 人脸识别 要实现人脸识别首先要判断当前图像中是否出现了人脸&#xff0c;这就是人脸检测。只有检测到图像中出现了人脸&#xff0c;才能据此判断这个人到底是谁。…

模拟电子电路基础(常见半导体+multisim学习1)

目录 1.半导体的基础 1.1.半导体基础知识 1.1.1本征半导体 1.1.2杂质半导体 1.1.3PN结 1.2半导体二极管 1.2.1半导体二极管的几种常见结构 1.2.2二极管的伏安特性曲线 1.2.3二极管的主要参数 1.2.4二级管的等效电路 1.2.5稳压二极管 1.2.其他类型二极管 2.multisim的…

计算机网络:数据链路层 —— PPP 点对点协议

文章目录 PPP 帧PPP帧的格式PPP帧的透明传输面向字节的异步链路面向比特的同步链路 PPP帧的差错检测 PPP 的工作状态 点对点协议&#xff08;Point-to-Point Protocol&#xff0c;PPP&#xff09;是目前使用最广泛的点对点数据链路层协议&#xff0c;用于在两个节点之间进行数据…

线性代数 行列式

一、行列式 1、定义 一个数学概念&#xff0c;主要用于 线性代数中&#xff0c;它是一个可以从方阵&#xff08;即行数和列数相等的矩阵&#xff09;形成的一个标量&#xff08;即一个单一的数值&#xff09; 2、二阶行列式 &#xff0c;像这样将一个式子收缩称为一个 2*2 的…

西门子828d的plc一些信息记录

1、虽然是200的plc但是引入了DB的形式替代原来的V存储区。 2、用户自定义DB块范围&#xff0c;DB9000-DB9063,共64个DB块。 可用地址范围如上图 机床MCP483面板地址表&#xff0c;其它类型的面板地址自己在828d简明调试手册里查看。 如何上载828d的plc程序&#xff1a; 1.通…

Chainlit集成Dashscope实现语音交互网页对话AI应用

前言 本篇文章讲解和实战&#xff0c;如何使用Chainlit集成Dashscope实现语音交互网页对话AI应用。实现方案是对接阿里云提供的语音识别SenseVoice大模型接口和语音合成CosyVoice大模型接口使用。针对SenseVoice大模型和CosyVoice大模型&#xff0c;阿里巴巴在github提供的有开…

数据结构之红黑树实现(全)

一、红黑树 红黑树是一种自平衡的二叉搜索树&#xff0c;它通过约束节点的颜色和结构来保持平衡。红黑树是由 Rudolf Bayer 在1972年发明的&#xff0c;被认为是一种优秀的平衡树结构&#xff0c;广泛应用于各种数据结构和算法中。 1.红黑树的性质 1. 每个结点是红的或者黑的…

Mac 备忘录妙用

之前使用 Windows 的过程中&#xff0c;最痛苦的事是没有一款可以满足我快速进行记录的应用 基本都得先打开该笔记软件&#xff0c;然后创建新笔记&#xff0c;最后才能输入&#xff0c;这么多步骤太麻烦了 在切换到 MacOS 之后&#xff0c;让我惊喜的就是自带的备忘录&#…

android——自定义控件(不停变化的textview、开关switch、动画效果的打勾)

一、从开始数字到结束数字&#xff0c;不断变化 import android.animation.TypeEvaluator; import android.animation.ValueAnimator; import android.content.Context; import android.util.AttributeSet; import android.view.animation.AccelerateDecelerateInterpolator;i…

设计模式-原型模式(克隆、Clone、Prototype)

原型模式&#xff08;克隆、Clone、Prototype&#xff09;是一种创建型设计模式&#xff0c; 使你能够复制已有对象&#xff0c; 而又无需使代码依赖它们所属的类。 问题 譬如美国研制了一种特效药&#xff0c;而且还在专利保护器内&#xff0c;而印度制药公司看中了&#xff0…

2024 第一次周赛

A: 题目大意 骑士每连续 i 天每天会得到 i 个金币&#xff0c;&#xff08;i 1&#xff0c; 2&#xff0c; 3 &#xff0c; …&#xff09;,那么展开看每一天可以得到的金币数&#xff1a;1 2 2 3 3 3 4 4 4 5 5 5 5 5 … 可以发现就是1个1 &#xff0c;2个2, 3个3…,那么我…