SpringCloud Alibaba之Seata分布式事务学习笔记(二)

简介: SpringCloud Alibaba之Seata分布式事务学习笔记(二)

2.2、采用file模式来集成seata服务


2.2.1、启动seata-server


服务端下载地址:seata-server 1.4.2,由于是外网下载太慢,可使用下面链接下载


链接:https://pan.baidu.com/s/1AqmcHZY9Op2IucG7rHbjOQ
提取码:bb6f


下载解压后的目录如下:



进入到bin目录之后,我们来进行输入命令执行其中bat工具,直接来启动服务就好(默认是file模式):



seata-server.bat -p 8868


指定在8868端口来进行执行,启动效果如下:



2.2.2、服务集成seata组件实现全局分布式事务



三个服务都进行集成seata依赖,主要配置步骤如下:


1、引入seata依赖:


<!--    引入seata依赖    -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>


2、配置文件来添加seata配置项,下面给出三个服务的不同配置项,下面需要特别注意的就是黄线的部分需要根据不同的服务名来进行配置:



seata-user-service:
seata:
  service:
    vgroup-mapping:
      # 这里需要对事务组做映射,默认的分组名为 应用名称-seata-service-group,将其映射到default集群
      # 这个很关键,一定要配置对,不然会找不到服务
      user-service-seata-service-group: default
    grouplist:
      default: localhost:8868


seata-book-service:


seata:
  service:
    vgroup-mapping:
        # 这里需要对事务组做映射,默认的分组名为 应用名称-seata-service-group,将其映射到default集群
        # 这个很关键,一定要配置对,不然会找不到服务
      book-service-seata-service-group: default
    grouplist:
      default: localhost:8868


seata-borrow-service:


seata:
  service:
    vgroup-mapping:
      # 这里需要对事务组做映射,默认的分组名为 应用名称-seata-service-group,将其映射到default集群
      # 这个很关键,一定要配置对,不然会找不到服务
      borrow-service-seata-service-group: default
    grouplist:
      default: localhost:8868


3、三个服务的启动器都去开启seata事务注解:


@EnableAutoDataSourceProxy //开启seata事务配置


4、在本地数据库中创建undo_log日志表


由于三个服务都使用的一个数据库seata-demo,所以我们直接在一个数据库中创建即可
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,
  `ext`           VARCHAR(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8;


5、最终在我们要进行分布式事务的service方法中添加全局事务注解!也就是borrow-service服务中的borrow()方法:


@GlobalTransactional



2.2.3、测试


提前准备


首先将seata-server服务器启动。


接着启动我们的三个服务:在启动时向seata-server去进行注册



看下seata-server服务的控制台:可以看到确实三个服务已经注册成功了



开始测试


首先来进行测试:http://localhost:8082/borrow/1/2



第一次借阅是没有问题的,看下数据库:



再次来进行借阅下:



ok,此时再看下数据库的各个表:原本在book表中产生问题的数据在这里就没有再出现了,可以看到中间出现异常能够成功回滚了



debug

我们在修改、删除操作上进行debug:



看下undo_log表:



扣减步骤完成后执行下一步:



再次看下undo_log表:



其中包含一个全局唯一xid:全局事务就是根据这一条记录来进行回滚管理的!


2.3、采用nacos模式服务


对于项目中引入依赖以及添加注解相关操作间2.2.2中的配置步骤,这里不再做演示。


2.3.1、配置完整步骤


1、在nacos中创建一个命名空间seata



2、修改配置文件


registry.conf:
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sof
  type = "nacos"
  nacos {
    # 应用名固定为seata-server
    application = "seata-server"
    # 注册中心的地址
    serverAddr = "127.0.0.1:8848"
    # 默认
    group = "SEATA_GROUP"
    # 命名空间的id
    namespace = "c30eb1d8-8e49-4b5d-beca-b1bf9479e94a"
    # 默认
    cluster = "default"
    # 连接用户名与密码
    username = "nacos"
    password = "nacos"
  }
}
config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"
  nacos {
    serverAddr = "127.0.0.1:8848"
    namespace = "c30eb1d8-8e49-4b5d-beca-b1bf9479e94a"
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
    dataId = "seataServer.properties"
  }
}



3、下载develop包,执行其中的script中脚本来对nacos的配置中心中seata命名空间配置项进行初始化:


下载地址:seata开发包


链接:https://pan.baidu.com/s/1iiQphUPbvgcIyXcIjUcjZA
提取码:cbr2


进入到其中nacos目录下执行脚本,在windows中我们使用git工具来使用:



./nacos-config-interactive.sh



最终效果如下:



4、手动在命名空间seata中添加三个服务的配置项:



service.vgroupMapping.user-service-seata-service-group   SEATA_GROUP   default
service.vgroupMapping.book-service-seata-service-group  SEATA_GROUP  default
service.vgroupMapping.borrow-service-seata-service-group  SEATA_GROUP  default


5、在三个服务项目中的各个服务添加配置项(替换之前的file模式):


# 2、nacos模式
seata:
  # 注册
  registry:
    # 使用Nacos
    type: nacos
    nacos:
      # 使用Seata的命名空间,这样才能正确找到Seata服务,由于组使用的是SEATA_GROUP,配置默认值就是,就不用配了
      namespace: c30eb1d8-8e49-4b5d-beca-b1bf9479e94a
      username: nacos
      password: nacos
  # 配置
  config:
    type: nacos
    nacos:
      namespace: c30eb1d8-8e49-4b5d-beca-b1bf9479e94a
      username: nacos
      password: nacos


6、关于nacos-server的会话存储位置(默认是file)


此时注册和配置相关的会话都继承在Nacos中进行了


还可以配置一下事务会话信息的存储方式,默认是file类型,那么就会在运行目录下创建file_store目录,可以看下启动seata-server后创建的文件效果:



6.1、其实我们可以将其搬到数据库中存储,只需要修改一下配置即可,在seata的命名空间中进行修改配置内容如下:


1、修改两个配置:store.session.mode、``store.mode的值为db`

2、接着我们对数据库信息进行一下配置:

数据库驱动(8.0的需要修改):com.mysql.cj.jdbc.Driver

数据库URL:默认就是seata数据库就好。

数据库用户名密码:store.db.user、store.db.password

6.2、创建一个数据库【seata】:



-- -------------------------------- The script used when storeMode is 'db' --------------------------------
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(255),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;
-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;
-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `status`         TINYINT      NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_status` (`status`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;
CREATE TABLE IF NOT EXISTS `distributed_lock`
(
    `lock_key`       CHAR(20) NOT NULL,
    `lock_value`     VARCHAR(20) NOT NULL,
    `expire`         BIGINT,
    primary key (`lock_key`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8mb4;
INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('HandleAllSession', ' ', 0);


那么配置就已经完成了!


2.3.2、测试

前提准备


启动nacos服务、seata服务如下:



执行seata启动的命令:


seata-server.bat -p 8868



启动三个服务:



与此同时,可以看到在seata服务的控制台中你可以看到里面的服务注册信息:



测试


访问借阅地址:http://localhost:8082/borrow/1/2



再此访问,肯定在中途去判断是否该用户借阅了书阶段出现异常,进行回滚,我们只需要关注book表中的书籍借阅数量有没有-1的问题,其实就是看其有没有回滚:



看下数据库:



没有问题!


2.3.3、debug


在这里我们来进行打上断点:



看看seata数据库以及我们自己本身的数据库undo_log中的记录是否产生变化:


接着来了一个请求,我们看debug的目前阶段:



此时来看数据库的情况:


seata数据库:记录依次是红框从上往下







seata-demo中的undo_log表:



可以看到用户表中的xid是依赖于tc也就是seata-server来进行回滚的。

相关文章
|
8月前
|
人工智能 Java Nacos
基于 Spring AI Alibaba + Nacos 的分布式 Multi-Agent 构建指南
本文将针对 Spring AI Alibaba + Nacos 的分布式多智能体构建方案展开介绍,同时结合 Demo 说明快速开发方法与实际效果。
5157 97
|
人工智能 负载均衡 Java
Spring AI Alibaba 发布企业级 MCP 分布式部署方案
本文介绍了Spring AI Alibaba MCP的开发与应用,旨在解决企业级AI Agent在分布式环境下的部署和动态更新问题。通过集成Nacos,Spring AI Alibaba实现了流量负载均衡及节点变更动态感知等功能。开发者可方便地将企业内部业务系统发布为MCP服务或开发自己的AI Agent。文章详细描述了如何通过代理应用接入存量业务系统,以及全新MCP服务的开发流程,并提供了完整的配置示例和源码链接。未来,Spring AI Alibaba计划结合Nacos3的mcp-registry与mcp-router能力,进一步优化Agent开发体验。
4044 14
|
消息中间件 运维 数据库
Seata框架和其他分布式事务框架有什么区别
Seata框架和其他分布式事务框架有什么区别
591 153
|
存储 SpringCloudAlibaba Java
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论。
【SpringCloud Alibaba系列】一文全面解析Zookeeper安装、常用命令、JavaAPI操作、Watch事件监听、分布式锁、集群搭建、核心理论
seata是怎么进行分布式事务控制的
seata是怎么进行分布式事务控制的
|
Java 关系型数据库 数据库
微服务SpringCloud分布式事务之Seata
SpringCloud+SpringCloudAlibaba的Seata实现分布式事务,步骤超详细,附带视频教程
1170 1
|
10月前
|
存储 负载均衡 NoSQL
【赵渝强老师】Redis Cluster分布式集群
Redis Cluster是Redis的分布式存储解决方案,通过哈希槽(slot)实现数据分片,支持水平扩展,具备高可用性和负载均衡能力,适用于大规模数据场景。
675 2
|
10月前
|
存储 缓存 NoSQL
【📕分布式锁通关指南 12】源码剖析redisson如何利用Redis数据结构实现Semaphore和CountDownLatch
本文解析 Redisson 如何通过 Redis 实现分布式信号量(RSemaphore)与倒数闩(RCountDownLatch),利用 Lua 脚本与原子操作保障分布式环境下的同步控制,帮助开发者更好地理解其原理与应用。
774 6
|
11月前
|
存储 缓存 NoSQL
Redis核心数据结构与分布式锁实现详解
Redis 是高性能键值数据库,支持多种数据结构,如字符串、列表、集合、哈希、有序集合等,广泛用于缓存、消息队列和实时数据处理。本文详解其核心数据结构及分布式锁实现,帮助开发者提升系统性能与并发控制能力。