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

news2024/11/24 22:47:54

一、基本概念

什么是数据库事务?

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 = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT 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: true
  application-id: ${spring.application.name}
  tx-service-group: my_seata_group
  enable-auto-data-source-proxy: true
  use-jdk-proxy: false
  excludes-for-auto-proxying: firstClassNameForExclude,secondClassNameForExclude
  client:
    rm:
      async-commit-buffer-limit: 1000
      report-retry-count: 5
      table-meta-check-enable: false
      report-success-enable: false
      saga-branch-register-enable: false
      lock:
        retry-interval: 10
        retry-times: 30
        retry-policy-branch-rollback-on-conflict: true
    tm:
      degrade-check: false
      degrade-check-period: 2000
      degrade-check-allow-times: 10
      commit-retry-count: 5
      rollback-retry-count: 5
    undo:
      data-validation: true
      log-serialization: jackson
      log-table: undo_log
      only-care-update-columns: true
    log:
      exceptionRate: 100
  service:
    vgroup-mapping:
      my_seata_group: default
    grouplist:
      default: localhost:8091
    enable-degrade: false
    disable-global-transaction: false
  transport:
    shutdown:
      wait: 3
    thread-factory:
      boss-thread-prefix: NettyBoss
      worker-thread-prefix: NettyServerNIOWorker
      server-executor-thread-prefix: NettyServerBizHandler
      share-boss-worker: false
      client-selector-thread-prefix: NettyClientSelector
      client-selector-thread-size: 1
      client-worker-thread-prefix: NettyClientWorkerThread
      worker-thread-size: default
      boss-thread-size: 1
    type: TCP
    server: NIO
    heartbeat: true
    serialization: seata
    compressor: none
    enable-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.coloradmin.cn/o/2211721.html

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

相关文章

NFT Insider #151:The Sandbox 推出 Alpha 第4季;腾讯或将收购育碧

市场数据 加密艺术及收藏品新闻 Beeple 将于 11 月在南京德基美术馆举办个人首展 著名数字艺术家 Beeple 近日在X平台发布视频&#xff0c;宣布将于 2024 年 11 月 14 日在南京德基美术馆举办个人首次展览&#xff0c;名为《Beeple&#xff1a;来自合成未来的故事》。该展览将…

JavaScript进阶--深入面向对象

深入面向对象 编程思想 面向过程&#xff1a;多个步骤> 解决问题 性能较高&#xff0c;适合跟硬件联系很紧密的东西&#xff0c;如单片机 但代码维护成本高&#xff0c;扩展性差 面向对象&#xff1a;问题所需功能分解为一个一个的对象&#xff08;分工合作&#xff09;>…

科研杂谈:24年诺奖颁布,AI竟是最终赢家?!

前言 2024年诺贝尔奖的公布引发了全球科学界的广泛关注&#xff0c;尤其是在人工智能&#xff08;AI&#xff09;领域的突破性获奖。诺贝尔物理学奖和化学奖相继颁给了在机器学习和蛋白质结构预测上取得重大进展的科学家们&#xff0c;让人们惊讶地看到AI正在迅速改变传统科研…

[Hbase]一 HBase基础

1. HBase简介 1.1 HBase定义 HBase数据模型的关键在于 稀疏、分布式、多维、排序 的映射。其中映射 map指代非关系型数据库的 key-Value结构。 1.2 HBase数据模型 1)Name Space 命名空间,类似于关系型数据库的database 概念,每个命名空间下有多个表。HBase 两个自…

【AI】AIGC浅析

引言 人工智能生成内容&#xff08;AIGC&#xff09;正迅速改变我们的生活、学习以及工作的方式。在计算机科学与技术领域、软件开发、大数据、智能网联汽车和车路云一体化行业&#xff0c;AIGC的应用已经成为行业发展的新动力。探讨AIGC对这些领域的影响、对职业技能需求的变化…

[Javase]封装、继承、多态与异常处理

文章目录 一、前言二、封装1、封装的思想2、封装代码层面的体现 三、继承1、继承的概念和好处2、继承代码层面的体现 四、多态1、多态的概念2、多态的好处和三要素2、多态代码层面的体现 五、异常处理1、try-catch-finally结构详解2、throw\throws 一、前言 本文章适合有一定面…

CMake 教程跟做与翻译 4

目录 添加一个option! 添加一个option! option&#xff0c;正如其意&#xff0c;就是选项的意思。我们这里需要演示一下option的做法。 option对于大型的工程必然是非常常见的&#xff1a;一些模块会被要求编译&#xff0c;另一些客户不准备需要这些模块。option就是将这种需…

【LLM KG】浅尝基于LLM的三阶段自动知识图谱构建方法

文章指出&#xff0c;在以前的方法中&#xff0c;使用LLM生成三元组时&#xff0c;必须预定义好schema&#xff0c;假如schema数量很多/复杂&#xff0c;很容易超过LLM的上下文窗口长度。并且&#xff0c;在某些情况下&#xff0c;没有可用的固定预定义schema。 方法 一、EDC…

计算机网络:数据链路层 —— 网络适配器与 MAC 地址

文章目录 网络适配器使用网络适配器网络适配器类型 MAC 地址MAC 地址格式MAC 地址类型MAC 地址发送顺序数据接收MAC 地址泄露问题 网络适配器 要将计算机连接到以太网&#xff0c;需要使用相应的网络适配器&#xff08;Adapter)&#xff0c;网络适配器一般简称为“网卡”。在计…

通信工程学习:什么是SRAM静态随机存取存储器

SRAM&#xff1a;静态随机存取存储器 SRAM&#xff0c;全称为Static Random-Access Memory&#xff0c;即静态随机存取存储器&#xff0c;是一种重要的随机存取存储器类型。以下是对SRAM的详细介绍&#xff1a; 一、定义与特点 定义&#xff1a; SRAM是一种只要保持通电&#…

CSS @规则(At-rules)系列详解___@import规则使用方法

CSS 规则(At-rules)系列详解 ___import规则使用方法 本文目录&#xff1a; 零、时光宝盒 一、import规则定义和用法 二、CSS import语法 2.1、语法格式 2.2、常见形式 2.3、语法说明 三、import使用方法例子 3.1、导入 CSS 规则 3.2、根据媒体查询条件导入 CSS 规则 …

结构体字节对齐的一些记录

‌结构体字节对齐的原因‌ 结构体字节对齐的主要原因是为了满足硬件平台的内存访问要求。某些硬件平台对特定类型的数据只能从特定的内存地址开始存取&#xff0c;如果数据没有进行对齐&#xff0c;可能会导致访问错误或效率低下。例如&#xff0c;某些架构的CPU在访问未对齐的…

原来CDC数据同步可以这么简单,零代码可视化一键数据同步

当前企业实时同步与分析场景中面临的挑战&#xff1a; 随着业务发展需要&#xff0c;实时分析成为企业目前的强需求&#xff0c;成为支撑企业业务发展的必须项。 一般来说&#xff0c;要满足数据实时分析的诉求&#xff0c;通常有两种方案&#xff1a; 第一种是直接使用源端…

多线程——解决线程安全问题

目录 前言 一、 synchronized 关键字 1. synchronized 的作用 1. synchronized 的特性 &#xff08;1&#xff09;互斥性 &#xff08;2&#xff09;可重入 2. synchronized 使用示例 &#xff08;1&#xff09;修饰代码块 &#xff08;2&#xff09;直接修饰普通方法…

Linux的GDB学习与入门

GDB GDB&#xff08;GNU Debugger&#xff09;是一个功能强大的调试工具&#xff0c;广泛用于调试 C、C 和其他编程语言编写的程序。它是 GNU 项目的一部分&#xff0c;专为帮助开发者在程序执行时检测和修复错误设计。GDB 能够控制程序的执行&#xff0c;查看程序内部的状态&…

2024诺奖引发思考,AI究竟是泡沫还是未来?

你好&#xff0c;我是三桥君 现在的AI技术发展得非常快&#xff0c;特别是深度学习和大模型这些技术&#xff0c;感觉和以前那些最后没搞成的技术泡沫不一样。 现在AI有超级强大的计算能力&#xff0c;还有大量的数据可以用来训练&#xff0c;算法也越来越厉害&#xff0c;能搞…

【单机游戏】【烛火地牢2:猫咪的诅咒】烛火地牢2:猫咪的诅咒介绍

《烛火地牢2&#xff1a;猫咪的诅咒》是一款将Roguelike与2D横版动作融为一体的独立游戏&#xff0c;由新西兰制作人Chris McFarland耗费3年时间精心制作。玩家将闯入不同的关卡接受挑战&#xff0c;通关要求是寻找每个关卡中的钥匙。在闯关时玩家能获得武器&#xff0c;防具&a…

关于int*的*号归属权问题

再根据函数指针定义&#xff1a;int (*int) (int a)。我们发现*和后面的标识符才是一体的 所以int *a,b;的写法更好&#xff0c;说明a是指针类型&#xff0c;b是int类型

让Kimi像人类思考的“Kimi探索版“已开启灰度内测!GPT-o1贡献者之一宣布离职|AI日报

文章推荐 “AI教父”辛顿与物理学家霍普菲尔德荣获诺贝尔物理学奖&#xff01;“AI教母”李飞飞选择谷歌云作为主要计算提供商&#xff5c;AI日报 今日热点 o1推理模型贡献者Luke Metz官宣从OpenAI离职 就在昨日&#xff0c;o1推理模型贡献者之一Luke Metz发文称自己经过两…

Ofcms-(java代码审计学习)

1、背景 根据《java代码审计实战》学习进行记录&#xff0c;java代码审计CMS实战。 2、Ofcms下载 可搜索Ofcms1.1.2版本进行下载。下载连接&#xff1a;ofcms: java 版CMS系统、基于java技术研发的内容管理系统、功能&#xff1a;栏目模板自定义、内容模型自定义、多个站点管…