Seata分布式事务实战AT模式

目录

分布式事务简介

典型的分布式事务应用场景

两阶段提交协议(2PC)

2PC存在的问题

什么是Seata?

Seata的三大角色

Seata AT模式的设计思路

一阶段

二阶段

Seata快速开始

Seata Server(TC)环境搭建

db存储模式+Nacos(注册&配置中心)方式部署

Seata Client快速开始

Spring Cloud Alibaba整合Seata AT模式实战


分布式事务简介

        在微服务架构中,完成某一个业务功能可能需要横跨多个服务,操作多个数据库。这就涉及到到了分布式事务,需要操作的资源位于多个资源服务器上,而应用需要保证对于多个资源服务器的数据操作,要么全部成功,要么全部失败。本质上来说,分布式事务就是为了保证不同资源服务器的数据一致性。

典型的分布式事务应用场景

跨库事务

跨库事务指的是,一个应用某个功能需要操作多个库,不同的库中存储不同的业务数据。

  

分库分表

通常一个库数据量比较大或者预期未来的数据量比较大,都会进行分库分表。

   

微服务架构

   

      Service A完成某个功能需要直接操作数据库,同时需要调用Service B和Service C,而Service B又同时操作了2个数据库,Service C也操作了一个库。需要保证这些跨服务调用对多个数据库的操作要么都成功,要么都失败。


两阶段提交协议(2PC)

两阶段提交(Two Phase Commit),就是将提交(commit)过程划分为2个阶段(Phase):

阶段1:

       TM通知各个RM准备提交它们的事务分支。如果RM判断自己进行的工作可以被提交,那就对工作内容进行持久化,再给TM肯定答复。要是发生了其他情况,那给TM的都是否定答复。

       以mysql数据库为例,在第一阶段,事务管理器向所有涉及到的数据库服务器发出prepare"准备提交"请求,数据库收到请求后执行数据修改和日志记录等处理,处理完成后只是把事务的状态改成"可以提交",然后把结果返回给事务管理器。

阶段2

       TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的RM都prepare成功,那么TM通知所有的RM进行提交。如果有RM prepare失败的话,则TM通知所有RM回滚自己的事务分支。

       以mysql数据库为例,如果第一阶段中所有数据库都prepare成功,那么事务管理器向数据库服务器发出"确认提交"请求,数据库服务器把事务的"可以提交"状态改为"提交完成"状态,然后返回应答。如果在第一阶段内有任何一个数据库的操作发生了错误,或者事务管理器收不到某个数据库的回应,则认为事务失败,回撤所有数据库的事务。数据库服务器收不到第二阶段的确认提交请求,也会把"可以提交"的事务回撤。

       两阶段提交方案下全局事务的ACID特性,是依赖于RM的。一个全局事务内部包含了多个独立的事务分支,这一组事务分支要么都成功,要么都失败。各个事务分支的ACID特性共同构成了全局事务的ACID特性。也就是将单个事务分支支持的ACID特性提升一个层次到分布式事务的范畴。


2PC存在的问题

同步阻塞问题

       2PC 中的参与者是阻塞的。在第一阶段收到请求后就会预先锁定资源,一直到 commit 后才会释放。

单点故障

       由于协调者的重要性,一旦协调者TM发生故障,参与者RM会一直阻塞下去。尤其在第二阶段,协调者发生故障,那么所有的参与者还都处于锁定事务资源的状态中,而无法继续完成事务操作。

数据不一致

       若协调者第二阶段发送提交请求时崩溃,可能部分参与者收到commit请求提交了事务,而另一部分参与者未收到commit请求而放弃事务,从而造成数据不一致的问题。


什么是Seata?

        Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)。

Seata的三大角色

在 Seata 的架构中,一共有三个角色:

  • TC (Transaction Coordinator) - 事务协调者

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

  • TM (Transaction Manager) - 事务管理器

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

  • RM (Resource Manager) - 资源管理器

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

其中,TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端。


Seata AT模式的设计思路

Seata AT模式的核心是对业务无侵入,是一种改进后的两阶段提交,其设计思路如下:

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

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

一阶段

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

二阶段

分布式事务操作成功,则TC通知RM异步删除undolog。

        分布式事务操作失败,TM向TC发送回滚请求,RM 收到协调器TC发来的回滚请求,通过 XID 和 Branch ID 找到相应的回滚日志记录,通过回滚记录生成反向的更新 SQL 并执行,以完成分支的回滚。


Seata快速开始

       Seata分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,TM和RM(Client端)由业务系统集成。

Seata Server(TC)环境搭建

Server端存储模式(store.mode)支持三种:

  • file:单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能较高。
  • db:高可用模式,全局事务会话信息通过db共享,相应性能差些。
  • redis:1.3及以上版本支持,性能较高,存在事务信息丢失风险,请提前配置适合当前场景的redis持久化配置。

资源目录:

  • client
    • 存放client端sql脚本,参数配置。
  • config-center
    • 各个配置中心参数导入脚本,config.txt(包含server和client)为通用参数文件。
  • server
    • server端数据库脚本及各个容器配置。

db存储模式+Nacos(注册&配置中心)方式部署

步骤一:下载安装包

Releases · apache/incubator-seata · GitHub

                

步骤二:建表(db模式)

创建数据库seata,执行sql脚本,https://github.com/seata/seata/tree/v1.5.1/script/server/db

步骤三:配置Nacos注册中心

       注册中心可以说是微服务架构中的”通讯录“,它记录了服务和服务地址的映射关系。在分布式架构中,服务会注册到注册中心,当服务需要调用其它服务时,就到注册中心找到服务的地址,进行调用。比如Seata Client端(TM,RM),发现Seata Server(TC)集群的地址,彼此通信。

注意:Seata的注册中心是作用于Seata自身的,和Spring Cloud的注册中心无关。

Seata支持的注册中心:

eureka、consul、nacos、etcd、zookeeper、sofa、redis、file (直连)

配置将Seata Server注册到Nacos,修改conf/application.yml文件

registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace:
      cluster: default
      username:
      password:

注意:请确保client与server的注册处于同一个namespace和group,不然会找不到服务。

启动 Seata-Server 后,会发现Server端的服务出现在 Nacos 控制台中的注册中心列表中。

步骤四:配置Nacos配置中心

        配置中心可以说是一个"大货仓",内部放置着各种配置文件,你可以通过自己所需进行获取配置加载到对应的客户端。比如Seata Client端(TM,RM),Seata Server(TC),会去读取全局事务开关,事务会话存储模式等信息。

注意:Seata的配置中心是作用于Seata自身的,和Spring Cloud的配置中心无关。

Seata支持的配置中心:

nacos、consul、apollo、etcd、zookeeper、file (读本地文件, 包含conf、properties、yml配置文件的支持)。

1)配置Nacos配置中心地址,修改conf/application.yml文件

seata:
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: 7e838c12-8554-4231-82d5-6d93573ddf32
      group: SEATA_GROUP
      data-id: seataServer.properties
     username:
     password:

2)上传配置至Nacos配置中心

https://github.com/seata/seata/tree/v1.5.1/script/config-center

a) 获取/seata/script/config-center/config.txt,修改为db存储模式,并修改mysql连接配置。

store.mode=db
store.lock.mode=db
store.session.mode=db
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true
store.db.user=root
store.db.password=root

b) 配置事务分组, 要与client配置的事务分组一致

  • 事务分组:seata的资源逻辑,可以按微服务的需要,在应用程序(客户端)对自行定义事务分组,每组取一个名字。
  • 集群:seata-server服务端一个或多个节点组成的集群cluster。 应用程序(客户端)使用时需要指定事务逻辑分组与Seata服务端集群的映射关系。

c) 在nacos配置中心中新建配置,dataId为seataServer.properties,配置内容为上面修改后的config.txt中的配置信息。

从v1.4.2版本开始,seata已支持从一个Nacos dataId中获取所有配置信息,你只需要额外添加一个dataId配置项。

步骤五:启动Seata Server

windows 直接启动bin/seata-server.bat

启动成功,查看控制台,账号密码都是seata。http://localhost:7091/

在Nacos注册中心中可以查看到seata-server注册成功


Seata Client快速开始

Spring Cloud Alibaba整合Seata AT模式实战

业务场景

用户下单,整个业务逻辑由三个微服务构成:

  • 库存服务:对给定的商品扣除库存数量。
  • 订单服务:根据采购需求创建订单。
  • 帐户服务:从用户帐户中扣除余额。

      

1) 环境准备

父pom指定微服务版本

Spring Cloud Alibaba Version

Spring Cloud Version

Spring Boot Version

Seata Version

2.2.8.RELEASE

Spring Cloud Hoxton.SR12

2.3.12.RELEASE

1.5.1

启动Seata Server(TC)端,Seata Server使用nacos作为配置中心和注册中心。

启动nacos服务。

2) 微服务导入seata依赖

spring-cloud-starter-alibaba-seata内部集成了seata,并实现了xid传递

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

3)微服务对应数据库中添加undo_log表(仅AT模式)

https://github.com/seata/seata/blob/v1.5.1/script/client/at/db/mysql.sql

-- 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';

4) 微服务application.yml中添加seata配置

seata:
  application-id: ${spring.application.name}
  # seata 服务分组,要与服务端配置service.vgroup_mapping的后缀对应
  tx-service-group: default_tx_group
  registry:
    # 指定nacos作为注册中心
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      namespace:
      group: SEATA_GROUP

  config:
    # 指定nacos作为配置中心
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: 7e838c12-8554-4231-82d5-6d93573ddf32
      group: SEATA_GROUP
      data-id: seataServer.properties

注意:请确保client与server的注册中心和配置中心namespace和group一致。

5) 在全局事务发起者中添加@GlobalTransactional注解

核心代码

@Override
@GlobalTransactional(name="createOrder",rollbackFor=Exception.class)
public Order saveOrder(OrderVo orderVo){
    log.info("=============用户下单=================");
    log.info("当前 XID: {}", RootContext.getXID());
    
    // 保存订单
    Order order = new Order();
    order.setUserId(orderVo.getUserId());
    order.setCommodityCode(orderVo.getCommodityCode());
    order.setCount(orderVo.getCount());
    order.setMoney(orderVo.getMoney());
    order.setStatus(OrderStatus.INIT.getValue());

    Integer saveOrderRecord = orderMapper.insert(order);
    log.info("保存订单{}", saveOrderRecord > 0 ? "成功" : "失败");
    
    //扣减库存
    storageFeignService.deduct(orderVo.getCommodityCode(),orderVo.getCount());
    
    //扣减余额
    accountFeignService.debit(orderVo.getUserId(),orderVo.getMoney());

    //更新订单
    Integer updateOrderRecord = orderMapper.updateOrderStatus(order.getId(),OrderStatus.SUCCESS.getValue());
    log.info("更新订单id:{} {}", order.getId(), updateOrderRecord > 0 ? "成功" : "失败");
    
    return order;
    
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

H5 个人引导页官网型源码

H5 个人引导页官网型源码 源码介绍&#xff1a;源码无后台、无数据库&#xff0c;H5自检测适应、无加密&#xff0c;直接修改可用。 源码含有多选项&#xff0c;多功能。可展示自己站点、团队站点。手机电脑双端。 下载地址&#xff1a; https://www.changyouzuhao.cn/1434.…

HTML+CSS+JS:轮播组件

效果演示 一个具有动画效果的卡片元素和一个注册表单&#xff0c;背景为渐变色&#xff0c;整体布局简洁美观。 Code <div class"card" style"--d:-1;"><div class"content"><div class"img"><img src"./i…

java接受命令行输入

在Java中&#xff0c;你可以使用​​Scanner​​类来接受命令行输入。以下是一个简单的例子&#xff0c;演示如何从命令行接受输入&#xff1a; import java.util.Scanner;public class CommandLineInputExample {public static void main(String[] args) {// 创建一个Scanner…

019 Spring Boot+Vue 电影院会员管理系统(源代码+数据库+文档)

部分代码地址&#xff1a; https://github.com/XinChennn/xc019-cinema 一、系统介绍 cinema项目是一套电影院会员管理系统&#xff0c;使用前后端分离架构开发包含管理员、会员管理、会员卡管理、电影票、消费记录、数据统计等模块 二、所用技术 后端技术栈&#xff1a; …

width:100%和width:auto有啥区别

项目中使用了with属性&#xff0c;突然好奇auto 和 100% 的区别&#xff0c;特地搜索实践总结了一下观点 一、 width属性介绍二、 代码带入三、 分析比较四、 总结 一、 width属性介绍 width 属性用于设置元素的宽度。width 默认设置内容区域的宽度&#xff0c;但如果 box-siz…

国创证券:迎政策助力,工业母机概念爆发,华中数控、宏德股份等涨停

工业母机概念26日盘中强势拉升&#xff0c;到发稿&#xff0c;华中数控、宏德股份“20cm”涨停&#xff0c;德恩精工、纽威数控涨超16%&#xff0c;科德数控、拓斯达等涨超10%&#xff0c;秦川机床、沈阳机床等亦涨停。 音讯面上&#xff0c;2月23日举行的中央财经委员会第四次…

C语言第三十一弹---自定义类型:结构体(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 目录 1、结构体内存对齐 1.1、为什么存在内存对齐? 1.2、修改默认对齐数 2、结构体传参 3、结构体实现位段 3.1、什么是位段 3.2、位段的内存分配 3.3、…

prime_series_level-1靶场详解

环境搭建 官网https://www.vulnhub.com/entry/prime-1,358/ 直接导入靶机 解题思路 arp-scan -l 确认靶机ip为192.168.236.136 也可以使用nmap扫网段 nmap -sn 192.168.236.0/24 使用nmap扫描靶机开放的端口 nmap -sS -T5 --min-rate 10000 192.168.236.136 -sC -p- &#xf…

BioVendor PEDF Human ELISA试剂盒

PEDF首先被发现是由人胎儿视网膜色素上皮细胞合成并释放到光感受器基质中的。它定位于人类染色体17p。PEDF是一种50 kDa多功能糖蛋白&#xff0c;属于丝氨酸蛋白酶抑制剂超基因(serpin)家族&#xff0c;作用类似丝氨酸蛋白酶的底物而不是抑制剂&#xff0c;也被描述为丝氨酸肽酶…

力扣模板题:回文链表

请牢记检测回文串的模板 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/ bool isPalindrome(struct ListNode* head) {int size0;struct ListNode* pointhead;while(point){size;pointpoint->next;}int arr…

遭遇DDOS攻击忍气吞声?立刻报警!首都网警重拳出击,犯罪分子无所遁形

遭遇DDOS攻击忍气吞声&#xff1f;立刻报警&#xff01;首都网警重拳出击 公元2024年2月24日18时许&#xff0c;笔者的个人网站突然遭遇不明身份者的DDOS攻击&#xff0c;且攻击流量已超过阿里云DDos基础防护的黑洞阈值&#xff0c;服务器的所有公网访问已被屏蔽&#xff0c;由…

高效项目计划的关键因素:制定前必须要考虑的事项

制定项目计划前需要考虑哪些因素&#xff1f;项目计划是一份重要的文件&#xff0c;它概述了项目的范围、目标、时间表、资源和预算。它作为项目团队和涉众的路线图&#xff0c;帮助每个人在整个项目生命周期中保持一致。在本文中我们将概述如何制定合理的项目计划。 1、定义项…

4.4 MySQL存储

目录 1、使用前提 2、使用连接数据库最初步骤 2.1 最初步骤 2.2 connect()方法中参数简单传递 3、创建数据库(创建架构)和创建表 3.1 创建数据库(创建架构) 3.2 创建表 3.2.1 基本创建 3.2.2 创建自增主键 4、Pycharm 可视化连接 MySQL 图形界面 5、插入、更新、查询…

centos升级g++.v6.1.0版本

1.下载源码包 wget http://ftp.gnu.org/gnu/gcc/gcc-6.1.0/gcc-6.1.0.tar.gz tar -zxvf gcc-6.1.0.tar.gz cd gcc-6.1.0 2.打开 download_prerequisites 脚本 vim contrib/download_prerequisites 可以看到该文件就是执行一些下载指令&#xff0c;需要下载几个包&#xff0c…

适合新手博主站长使用的免费响应式WordPress博客主题JianYue

这款JianYue主题之所以命名为 JianYue&#xff0c;意思就是简单而不简约的。是根据Blogs主题优化而成&#xff0c;剔除了一些不必要的功能及排版&#xff0c;仅保留一种博客布局&#xff0c;让新手站长能够快速手上WordPress。可以说这款主题比较适合新手博主站长使用&#xff…

数字化转型导师坚鹏:省级政府数字化转型案例研究

省级政府数字化转型案例研究 课程背景&#xff1a; 很多省级政府存在以下问题&#xff1a; 不清楚省级政府数字化转型的政务服务类成功案例 不清楚省级政府数字化转型的社会管理类成功案例 不清楚省级政府数字化转型的数字机关类成功案例 不清楚省级政府数字化转型的…

比创达元启新程 共创新佳绩:2023年度总结暨迎新年晚会圆满收官!

新的一年&#xff0c;万象更新。回顾2023年&#xff0c;我们携手走过的岁月&#xff0c;喜悦伴着汗水&#xff0c;成功伴着艰辛&#xff0c;遗憾激励奋斗。在过去的一年时间里&#xff0c;每个行业都经历着前所未有的变革与困难。我们比创达人也凭借着人心齐泰山移的团结之力&a…

智能SQL生成:后端技术与LLM的完美结合

文章目录 引言一、什么是大模型二、为什么选择LLM三、开发技术说明四、系统架构说明五、编码实战1. Maven2. 讯飞大模型配置类3. LLM相关的封装4. 编写LLM的service5. 编写controller6. 运行测试 六、总结 引言 本篇文章主要是关于实现一个类似Chat2DB的根据自然语言生成SQL的…

产品经理应该具备的基本意识(3)团灭意识(字幕)

1 00:00:01,040 --> 00:00:02,440 下一个基本意识 2 00:00:02,450 --> 00:00:05,310 我们就要有一个团灭意识 3 00:00:06,320 --> 00:00:09,070 我们在软件方法第二章的时候也说过 4 00:00:09,080 --> 00:00:11,580 就是说&#xff0c;我们做需求的时候 5 00:0…

【Java程序设计】【C00307】基于Springboot的基Hadoop的物品租赁管理系统(有论文)

基于Springboot的基Hadoop的物品租赁管理系统&#xff08;有论文&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的基于 Hadoop的物品租赁系统的设计与实现&#xff0c;本系统有管理员、用户二种角色权限&#xff1b; 前台首页&#…