当前位置:首页 >知识 >SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

2024-04-28 19:01:32 [百科] 来源:避面尹邢网

SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

作者:Springboot实战案例锦集 开发 前端 什么是整注册置配置中心?配置中心可以说是一个"大衣柜",内部放置着各种配置文件,你可以通过自己所需进行获取配置加载到对应的客户端.比如Seata Client端(TM,RM),Seata Server(TC),会去读取全局事务开关,事务会话存储模式等信息.

环境:springboot2.3.11.RELEASE + spring cloud Hoxton.SR8 + spring cloud alibaba 2.2.5.RELEASE + seata1.3.0

前提:安装并启动了nacos服务

SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

Seata注册中心及配置中心说明

SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

配置中心

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

SpringCloud整合Seata实现分布式事务通过nacos实现注册和配置

Seata的配置中心与Spring cloud的配置中心区别是?在广义上来说,并无区别,只不过Spring cloud的配置中心仅是作用于它们自身的组件,而Seata的配置中心也是一样是作用于Seata自身.(注:Spring cloud的配置中心与Seata无关)

注册中心

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

Seata的注册中心与Dubbo,Spring cloud的注册中心区别是?在广义上来说,并无区别,只不过Dubbo与Spring cloud的注册中心仅是作用于它们自身的组件,而Seata的注册中心也是一样是作用于Seata自身.(注:Dubbo与Spring cloud的注册中心与Seata无关)

Seata服务配置

1、在%SEATA_HOME%目录下新建config.txt文件

service.vgroupMapping.dt-group=defaultstore.mode=dbstore.db.datasource=druidstore.db.dbType=mysqlstore.db.driverClassName=com.mysql.cj.jdbc.Driverstore.db.url=jdbc:mysql://127.0.0.1:3306/seata?分布useUnicode=true&serverTimezone=GMT%2B8store.db.user=rootstore.db.password=xxxxxxstore.db.minConn=5store.db.maxConn=30store.db.globalTable=global_tablestore.db.branchTable=branch_tablestore.db.queryLimit=100store.db.lockTable=lock_tablestore.db.maxWait=5000

2、执行脚本

通过如下地址下载脚本执行

图片

在windows系统下可以通过 git bash 来执行shell脚本

sh nacos-config.sh -h nacos的整注册置ip -p nacos端口 -g nacos配置文件的组 -t 你的namespace号(若是public可省略此选项) -u nacos用户名 -w nacos密码

3、数据库初始化脚本

CREATE TABLE `undo_log` (  `id` bigint(20) NOT NULL AUTO_INCREMENT,合S和配  `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;-- the table to store GlobalSession dataCREATE 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(32),    `transaction_name`          VARCHAR(128),    `timeout`                   INT,    `begin_time`                BIGINT,    `application_data`          VARCHAR(2000),    `gmt_create`                DATETIME,    `gmt_modified`              DATETIME,    PRIMARY KEY (`xid`),    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),    KEY `idx_transaction_id` (`transaction_id`)) ENGINE = InnoDB  DEFAULT CHARSET = utf8;-- the table to store BranchSession dataCREATE 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 = utf8;-- the table to store lock dataCREATE TABLE IF NOT EXISTS `lock_table`(    `row_key`        VARCHAR(128) NOT NULL,    `xid`            VARCHAR(96),    `transaction_id` BIGINT,    `branch_id`      BIGINT       NOT NULL,    `resource_id`    VARCHAR(256),    `table_name`     VARCHAR(32),    `pk`             VARCHAR(36),    `gmt_create`     DATETIME,    `gmt_modified`   DATETIME,    PRIMARY KEY (`row_key`),    KEY `idx_branch_id` (`branch_id`)) ENGINE = InnoDB  DEFAULT CHARSET = utf8;

完成以上步骤后查看nacos配置

接下来进行项目开发及配置接下来进行项目开发及配置

项目结构

图片图片

两个子模块:

dt-account-service 用户模块
dt-storage-service 库存模块

父工程依赖

<dependencies>  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-data-jpa</artifactId>  </dependency>  <dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-web</artifactId>  </dependency>  <dependency>    <groupId>com.alibaba.cloud</groupId>    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>    <exclusions>      <exclusion>        <groupId>io.seata</groupId>        <artifactId>seata-all</artifactId>      </exclusion>    </exclusions>  </dependency>  <dependency>    <groupId>mysql</groupId>    <artifactId>mysql-connector-java</artifactId>  </dependency>  <dependency>    <groupId>org.springframework.cloud</groupId>    <artifactId>spring-cloud-starter-openfeign</artifactId>  </dependency>  <dependency>    <groupId>io.seata</groupId>    <artifactId>seata-all</artifactId>    <version>${ seata.version}</version>  </dependency></dependencies><dependencyManagement>  <dependencies>    <dependency>      <groupId>com.alibaba.cloud</groupId>      <artifactId>spring-cloud-alibaba-dependencies</artifactId>      <version>${ spring-cloud-alibaba.version}</version>      <type>pom</type>      <scope>import</scope>    </dependency>    <dependency>      <groupId>org.springframework.cloud</groupId>      <artifactId>spring-cloud-dependencies</artifactId>      <version>${ spring-cloud.version}</version>      <type>pom</type>      <scope>import</scope>    </dependency>  </dependencies></dependencyManagement>

account帐号模块

核心配置文件

spring:  cloud:    nacos:      password: nacos      username: nacos      discovery:        server-addr: 118.24.111.33:8848        namespace: ""        group: dt-group---seata:  tx-service-group: dt-group  registry:    type: nacos    nacos:      application: seata-server #这里要与seata中的registry.conf配置的application一致      group: dt-group      namespace: ""      server-addr: 118.24.111.33:8848      username: nacos      password: nacos  config:    type: nacos    nacos:      namespace: ""      group: dt-group      server-addr: 118.24.111.33:8848      username: nacos      password: nacos

AccountService服务类

@Servicepublic class AccountService {   private static final String ERROR_USER_ID = "1002";  @Resource  private AccountMapper accountMapper ;  @Resource  private StorageFeignClient storageFeignClient;  @Transactional(rollbackFor = Exception.class)  @GlobalTransactional  public void debit(String userId, BigDecimal num, String commodityCode, int orderCount) {     System.out.println(RootContext.getXID()) ;    accountMapper.updateAccount(num, userId) ;    storageFeignClient.deduct(commodityCode, orderCount);    try {       TimeUnit.MILLISECONDS.sleep(new Random().nextInt(100)) ;    } catch (InterruptedException e) {       e.printStackTrace();    }            if (ERROR_USER_ID.equals(userId)) {       throw new RuntimeException("account branch exception");    }  }    }

这里模拟了抛出异常当输入的userId为1002时抛出异常,就为了测试所有服务的实现式事实现事务是否回滚了。注意这里需要添加@GlobalTransactional注解

Feign接口

@FeignClient(name = "storage-service",分布 url = "127.0.0.1:8802")public interface StorageFeignClient {   @GetMapping("/storage/deduct")  void deduct(@RequestParam("commodityCode") String commodityCode, @RequestParam("count") Integer count);}

storage库存子模块

该子模块的配置与account模块的配置基本一致

StorageService

@Servicepublic class StorageService {   @Resource  private StorageMapper storageMapper ;  @Transactional  public void deduct(String commodityCode, int count) {     System.out.println(RootContext.getXID()) ;    storageMapper.updateStorage(count, commodityCode) ;  }}

测试

启动seata,nacos,整注册置account,合S和配storage服务后查看nacos

图片图片


seata服务也已经注册上来了。实现式事实现

数据库初始化数据

图片图片


图片图片

正常请求

图片图片

数据变化

图片图片


当传入userId=1002时

图片图片


account模块控制台

图片图片


storage模块控制台

图片图片


数据库数据

图片图片


数据没有任何变化说明回滚了

责任编辑:武晓燕 来源: 实战案例锦集 配置中心SeataClient端

(责任编辑:休闲)

    推荐文章
    热点阅读