Springboot+nacos+seata实现简单分布式事务经验分享:一

Springboot+nacos+seata实现简单的分布式事务

*书接上回,上一篇文章搭建的nacos注册中心,本次要把seata服务和三个springboot服务集成进去

seata集成nacos

  1. 下载seata,下载地址: https://github.com/seata/seata/releases
    这里我下载的是1.6.1的版本
    在这里插入图片描述
    选择这个压缩包,下载好解压后我们还要修改一下配置文件。
    在修改配置文件之前我们还需要在nacos管理页面进行配置
    在这里插入图片描述
    在左侧菜单栏选择命名空间,然后新建命名空间,当然你也可以不用自己新建,可以用默认的public。我这里为了区分,创建了名为seata的空间

好了,我们开始需改seata的配置文件。
首先:打开conf目录下的application.yml和application.example.yml文件。刚解压的application.yml文件里面配置都是空的,需要application.example.yml文件里提供的模板。

第一步:修改以上seata服务的注册方式和配置方式,各参数详情如下图:
在这里插入图片描述

第二步:修改存储模式配置文件,这里我用的db模式,在 db 模式下,我们需要针对全局事务的会话信息创建以下 3 张数据库表。
1:全局事务表,对应的表为:global_table
2:分支事务表,对应的表为:branch_table
3:全局锁表,对应的表为:lock_table

global_table

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

branch_table

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 = utf8;

lock_table

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

第三步:启动bin目录下的seata-server.bat,出现下图所示就代表启动成功了
在这里插入图片描述
接着我们去nacos查看
在这里插入图片描述
seata服务已经注册进去了。好了,接下来我们要创建三个服务了

在这里我用idea创建了三个服务:
在这里插入图片描述
打开springdemoOrder项目先引入依赖包,我这创建了三个服务,使用openfeign实现相互调用,所要导入的包有:openfeign相关的依赖包,mysql依赖包,seata依赖包,nacos相关依赖包

openfeign相关的依赖包

<dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
		<groupId>org.springframework.cloud</groupId>
		<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

mysql依赖包

<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
         <version>5.1.47</version>
</dependency>

seata依赖包

<dependency>
        <groupId>io.seata</groupId>
        <artifactId>seata-spring-boot-starter</artifactId>
        <version>1.6.1</version>
</dependency>

nacos相关依赖包

<dependency>
        <groupId>com.alibaba.nacos</groupId>
        <artifactId>nacos-client</artifactId>
        <version>2.2.0</version>
</dependency>

<dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <version>2.1.1.RELEASE</version>
        <exclusions>
                <!-- 将ribbon排除 -->
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
                </exclusion>
           </exclusions>
</dependency>
<dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
        <version>2.2.5.RELEASE</version>
</dependency>

nacos的依赖中,我把ribbon排除,至于为什么排除到后面出错的时候说一下。三个服务都用上面的依赖

依赖导入完成我们要创建配置文件了,创建application.yml文件,我的配置文件如下:

server:
  port: 8080
spring:
  application:
    name: seataOrder #服务名
#  main:
#    allow-bean-definition-overriding: true
  datasource:
    driver-class-name: com.mysql.jdbc.Driver #数据库驱动
    url: jdbc:mysql://xxxxxx/xxx?characterEncoding=utf-8&serverTimeZone=GMT%2B8&useSSL=false
    username: xxx
    password: xxx
  cloud:
    nacos:
      discovery:
        ip: 127.0.0.1:8080
        autoRegister: true
        server-addr: 127.0.0.1:8848 #nacos 服务器地址
        namespace: seata #nacos 命名空间
        username: nacos
        password: nacos
        group: SEATA_GROUP
      config:
        username: nacos
        password: nacos
        context-path: /nacos
        server-addr: 127.0.0.1:8848 # 设置配置中心服务端地址
        namespace: seata
    alibaba:
      seata:
        #自定义服务群组,该值必须与 Nacos 配置中的 service.vgroupMapping.{my-service-group}=default 中的 {my-service-group}相同
        tx-service-group: order
seata:
  application-id: ${spring.application.name}
  tx-service-group: order
#  enable-auto-data-source-proxy: false
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848 # Nacos 注册中心的地址
      group: "SEATA_GROUP" #分组,这里和配置文件里的一样
      namespace: "seata"  # Nacos 注册中心的配置ID
      username: "nacos"   # Nacos 注册中心的用户名
      password: "nacos"   # Nacos 注册中心的密码
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: "seata"
      group: SEATA_GROUP
      username: "nacos"
      password: "nacos"
  service:
    vgroup-mapping:
      my_test_tx_group: default
management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details=always:
feign:
  sentinel:
    enabled: true #开启 OpenFeign 功能

配置完成后启动一下试试,看看效果
在这里插入图片描述
已经注册进nacos里了,看看seata服务的订阅者下有没有order服务,结果如下图
在这里插入图片描述
启动另外两个服务,配置文件和上面的一样,不过下面这两个参数需要修改
在这里插入图片描述

在这里插入图片描述
修改完后启动另外两个服务,如出现下图红框的标识就代表三个都注册进去了
在这里插入图片描述

在这里插入图片描述
然后打开seata订阅者列表看看在这里插入图片描述
结果发现只有一个订阅者,应用名为unknow,着没道理啊,后来我在每个服务的启动参数里加上了:-Dproject.name =xxx就行了
在这里插入图片描述
再次启动发现正常,应该是没有
在这里插入图片描述
我猜测大概是三个服务都应用名都是一样的就会发生覆盖。这篇就先这样了,下一篇在写业务代码

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 Spring Boot 和 Spring Cloud Alibaba Seata 实现分布式事务需要以下步骤: 1. 添加依赖:在 pom.xml 中添加 seata-all 和 seata-spring-boot-starter 依赖。 2. 配置 Seata:在 application.properties 或 application.yml 中配置 Seata Server 的地址和端口,以及各个事务组的配置信息。 3. 配置数据源代理:使用 Seata 提供的数据源代理,将原本的数据源替换为 Seata 提供的代理数据源。 4. 配置分布式事务注解:在需要进行分布式事务的方法上添加 @GlobalTransactional 注解。 下面是一个示例 application.yml 配置文件: ```yaml spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: root driver-class-name: com.mysql.jdbc.Driver seata: enabled: true application-id: demo-app tx-service-group: my_tx_group config: type: nacos nacos: serverAddr: localhost:8848 namespace: public service: vgroupMapping: my_test_tx_group: default groupMapping: my_test_tx_group: "DEMO_GROUP" datasources: ds: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test username: root password: root type: com.alibaba.druid.pool.DruidDataSource maxPoolSize: 20 minPoolSize: 1 initialSize: 1 maxLifetime: 1800000 validationQuery: select 1 validationQueryTimeout: 30000 testOnBorrow: true testWhileIdle: true testOnReturn: false ``` 在代码中使用 @GlobalTransactional 注解: ```java @Service public class OrderServiceImpl implements OrderService { @Autowired private OrderMapper orderMapper; @Autowired private AccountClient accountClient; @Autowired private StorageClient storageClient; @GlobalTransactional @Override public void create(Order order) { // 1. 创建订单 orderMapper.create(order); // 2. 扣减库存 storageClient.deduct(order.getProductId(), order.getCount()); // 3. 扣减账户余额 accountClient.deduct(order.getUserId(), order.getMoney()); // 4. 修改订单状态 orderMapper.update(order.getUserId(), 0); } } ``` 其中,AccountClient 和 StorageClient 是通过 Feign 实现的远程调用,这些服务也需要添加 Seata 的依赖和配置。 这样就可以实现分布式事务了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值