分布式事务seaeta的file或配置注册中心采用naocs模式启动以及配置本地多个服务实例方法(亲测有效)

注:启动server端多个实例

如图所示:新建一个maven项目新增Program arguments -p 端口号
在这里插入图片描述

1.file模式下启用seata配置

一.修改seata-server文件

  1. 首先是在seata官网下载seata相对应的服务端版本,注意服务端和客户端的版本冲突问题,具体可阅读官网。这里我采用的是server端是1.4.2(官方回复此版本有bug只可做为demo测试使用,建议升级至1.7.0最新版本.Nacos版本可不变动)
  2. 修改源码上的registry.conf文件。将registry和config的type修改为file.如下图展示在这里插入图片描述在这里插入图片描述
  3. 修改file文件
service {
  # 事务组名称
  vgroup_mapping.my-tx-group = "seata-server"
  disableGlobalTransaction = false
}

如图展示:

在这里插入图片描述

4.根据seata-server源码上的脚本创建本地seata库。

二.client端配置

  1. 在resources目录下新建file.conf文件
service {
  # 事务组名称
  vgroup_mapping.my-tx-group = "seata-server"
  #服务端server地址
  default.grouplist="127.0.0.1:9091"
}

  1. 修改application.properties文件
# seata 配置
seata.application-id=demo
seata.enabled=true
seata.tx-service-group=my-tx-group
seata.service.grouplist.seata-server=127.0.0.1:9091
seata.service.vgroup-mapping.my-tx-group=seata-server

三.启动server端和client端检查控制台日志信息

服务端日志如下:
在这里插入图片描述可以从server端看出RM和TM 都注册成功。

客户端日志如下:
在这里插入图片描述
连接到server端成功。至此file模式下启动分布式事务启动成功。但实际线上环境要保证数据持久化以及服务高可用一般采用db+nacos启用分布式事务。

2.Nacos+DB模式下启用seata配置

其他配置中心类似

一.下载并启动Nacos

  1. Nacos下载并修改为单机模式,win下进入bin下编辑startup.cmd。加入 set MODE=“standalone”,页面如下图所示。单机启动。根据需求可建立namespace空间。
    在这里插入图片描述
    在这里插入图片描述

二.配置seata-server为nacos方式启动

  1. 修改registry.conf 注册配置和配置中心配置为nacos方式,并配置对应的namespace地址,用户名密码,serverAddr和group如下图展示:
    在这里插入图片描述
    注意使用dataId指定服务端读取的配置文件,如图:
    在这里插入图片描述

三.启动seata-server

启动后可在nacos控制台上看到服务端有注册到nacos且只有一个实例。
在这里插入图片描述

四.客户端配置

  1. 引入nacos依赖和seata依赖,注意我这里的springboot版本为2.0.1.RELEASE
   <dependency>
            <groupId>io.seata</groupId>
            <artifactId>seata-spring-boot-starter</artifactId>
            <version>1.4.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>1.4.2</version>
        </dependency>
  1. yml文件配置如下:
spring:
  datasource:
    druid:
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db?serverTimezone=UTC
      username: root
      password: root
  application:
    name: springboot-seata-demo
server:
  port: 80
#seata配置
seata:
#id必须要配置,否则会报错
  application-id: springboot-seata
  enabled: true
  #配置中心
  config:
    type: nacos
    nacos:
      username: nacos
      password: nacos
      group: SEATA_GROUP
      server-addr: localhost:8848
      namespace: xxxxxxxxxxx
      #读取nacos上的的配置文件(自己命名)
      data-id: seata-client.properties

  registry:
    type: nacos
    nacos:
      application: seata-server
      group: SEATA_GROUP
      server-addr: localhost:8848
      namespace: xxxxxxxxxxx
      username: nacos
      password: nacos
      cluster: default
  # seata 事务组编号 用于TC集群名
  tx-service-group: seata_service_group
  enable-auto-data-source-proxy: true
  service:
    #    grouplist: 只会在file格式下起作用
    #      defalut: 127.0.0.1:9091
    vgroupMapping:
      seata_service_group: default
  data-source-proxy-mode: AT

  1. seata-client.properties配置文件如下
transport.type=TCP
transport.server=NIO
transport.heartbeat=true
transport.enableClientBatchSendRequest=true
transport.threadFactory.bossThreadPrefix=NettyBossDigiwin
transport.threadFactory.workerThreadPrefix=NettyServerNIOWorker
transport.threadFactory.serverExecutorThreadPrefix=NettyServerBizHandler
transport.threadFactory.shareBossWorker=false
transport.threadFactory.clientSelectorThreadPrefix=NettyClientSelector
transport.threadFactory.clientSelectorThreadSize=1
transport.threadFactory.clientWorkerThreadPrefix=NettyClientWorkerThread
transport.threadFactory.bossThreadSize=1
transport.threadFactory.workerThreadSize=default
transport.shutdown.wait=3
transport.serialization=seata
transport.compressor=none
client.rm.asyncCommitBufferLimit=10000
client.rm.lock.retryInterval=10
client.rm.lock.retryTimes=30
client.rm.lock.retryPolicyBranchRollbackOnConflict=true
client.rm.reportRetryCount=5
client.rm.tableMetaCheckEnable=false
client.rm.tableMetaCheckerInterval=60000
client.rm.sqlParserType=druid
client.rm.reportSuccessEnable=false
client.rm.sagaBranchRegisterEnable=false
client.rm.tccActionInterceptorOrder=-2147482648
client.tm.commitRetryCount=5
client.tm.rollbackRetryCount=5
client.tm.defaultGlobalTransactionTimeout=60000
client.tm.degradeCheck=false
client.tm.degradeCheckAllowTimes=10
client.tm.degradeCheckPeriod=2000
client.tm.interceptorOrder=-2147482648
client.undo.dataValidation=true
client.undo.logSerialization=jackson
client.undo.onlyCareUpdateColumns=true
client.undo.logTable=undo_log
client.undo.compress.enable=true
client.undo.compress.type=zip
client.undo.compress.threshold=64k
#此配置必须要有而且必须和本地配置文件一致
service.vgroupMapping.seata_service_group=default
service.enableDegrade=false
service.disableGlobalTransaction=false
  1. seataServer.properties 配置文档如下:
# 存储模式
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
# 需要根据mysql的版本调整driverClassName
# mysql8及以上版本对应的driver:com.mysql.cj.jdbc.Driver
# mysql8以下版本的driver:com.mysql.jdbc.Driver
store.db.driverClassName=com.mysql.jdbc.Driver
# 注意根据生产实际情况调整参数host和port
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
# 数据库用户名
store.db.user=root
# 用户名密码
store.db.password=root

# 开启监控
metrics.enabled=true
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

minConn=5
maxConn=100
globalTable="global_table"
branchTable="branch_table"
lockTable="lock_table"
queryLimit=100
maxWait=5000

server.recovery.committingRetryPeriod=1000
server.recovery.asynCommittingRetryPeriod=1000
server.recovery.rollbackingRetryPeriod=1000
server.recovery.timeoutRetryPeriod=1000
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.distributedLockExpireTime=10000

五.启动客户端,同时检查nacos控制台,seata-server控制台日志以及客户端日志。成功如下图展示
nacos:
在这里插入图片描述
seata-server:
在这里插入图片描述
client:
在这里插入图片描述

五.解决 客户端订阅者的应用名为unknown

@Configuration
public class ProjectNameConfig implements EnvironmentAware {
    @Value("${spring.application.name}")
    private  String applicationName;

    @Override
    public void setEnvironment(Environment environment) {
        if(StringUtils.isBlank(System.getProperty("project.name"))){
            System.setProperty("project.name",applicationName);
        }
    }
}

3.检验:同项目下多库验证seata功能

一. 引入dynamic依赖包,支持一个项目多个库的场景

 <!-- dynamic-datasource-spring-boot-starter动态数据源 -->
        <!-- 支持多数据源,,一个项目多个库的场景。 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

二. 本地mysql环境新增了三个库分别为:seata-order ,seata-account,seata-product。

三个库下分别存储了业务表外注意每个库下都必须要走undo_log表。

DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NULL DEFAULT NULL,
  `product_id` int(11) NULL DEFAULT NULL,
  `pay_amount` int(11) NULL DEFAULT NULL,
  `add_time` datetime NULL DEFAULT NULL,
  `update_time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 55 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Table structure for product
-- ----------------------------
DROP TABLE IF EXISTS `product`;
CREATE TABLE `product`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `price` int(11) NULL DEFAULT NULL,
  `stock` int(11) NULL DEFAULT NULL,
  `add_time` datetime NULL DEFAULT NULL,
  `update_time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of product
-- ----------------------------
INSERT INTO `product` VALUES (1, '电池', 10, 62, '2021-01-15 00:00:32', '2021-01-15 00:00:35');

-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NULL DEFAULT NULL,
  `balance` int(11) NULL DEFAULT NULL,
  `update_time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, 1, 150, '2021-01-15 00:02:17');


DROP TABLE IF EXISTS `undo_log`;
CREATE TABLE `undo_log`  (
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

三. 配置多数据源

spring:
  datasource:
    dynamic:
      seata: true
      #必须要指定主数据源否则无法启动项目
      primary: seata-orders
      datasource:
        #多数据源设置订单数据源
        seata-orders:
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: root
          url: jdbc:mysql://127.0.0.1:3306/seata_orders?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false

        #account 数据源配置
        seata-account:
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: root
          url: jdbc:mysql://127.0.0.1:3306/seata_account?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false
        #product 数据源配置
        seata-product:
          driver-class-name: com.mysql.jdbc.Driver
          username: root
          password: root
          url: jdbc:mysql://127.0.0.1:3306/seata_product?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false

四. 分别启动seata-sever和client项目即可找到对应的注册和连接成功日志。seata-server日志截图:

在这里插入图片描述
客户端截图:
在这里插入图片描述

五. 发起访问请求,如图所示:

debug:
当日志出现:Begin new global transaction [192.168.7.27:9091:7053067194827630891] 代表已经发起了一段全局事务的请求以及生成了贯穿全局的Xid(192.168.7.27:9091:7053067194827630891),日志如下
在这里插入图片描述
以及扣减库存和减余额的库的undo_log表中生成量两行分支id日志:
在这里插入图片描述
在这里插入图片描述

六. 修改seata默认超时时间

seata的默认超时时间为60000(1分钟)。为了方便演示我在debug上停留了1分钟以上,则会导致找不到xid,seata已经提前结束这段全局事务的行动。报错信息如下:
在这里插入图片描述
7. 建议将默认时间延长,我目前修改的时间为十分钟。修改seata-client.propertis(client.tm.defaultGlobalTransactionTimeout=600000)
数据正常回滚和流转。

4.启动seata-server两个实例,检查服务端稳定性。

  1. 启动两个实例,则可在nacos中看到注册有两个实例服务。
    在这里插入图片描述
  2. 客户端发起请求,可看出访问的服务是随机模式。
    访问到端口为9092的seata服务截图如下:
    在这里插入图片描述
    访问到端口为9092的seata服务截图如下:
    在这里插入图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要测试分布式事务功能并确保 Seata 的正确安装和配置,您可以按照以下步骤操作: 1. 确保您已经正确安装了 Seata。您可以从 Seata 的官方网站或 GitHub 上获取最新的发布版本,并按照官方文档的指引进行安装和配置。 2. 配置 Seata注册中心。根据您的需求选择合适的注册中心,比如 Nacos、ZooKeeper 或者 eureka,并确保 Seata注册中心能够正常通信。 3. 配置 Seata 的存储模式Seata 支持多种存储模式,比如 file、db 和 redis。根据您的需求选择合适的存储模式,并进行相应的配置。 4. 在您的应用程序中引入 Seata 的相关依赖,并配置相应的事务管理器。具体配置方式可以参考 Seata 的官方文档。 5. 编写测试代码,模拟分布式事务的场景。可以通过在不同的服务之间调用接口,并在事务中执行相关操作来模拟分布式事务。 6. 运行测试代码,并观察事务是否能够正常提交或回滚。通过观察日志或查询数据库来验证事务的正确性。 如果测试过程中遇到问题,可以通过查看日志、调试代码或查阅 Seata 的官方文档来进行故障排查和解决。 请注意,以上步骤仅提供了一个大致的测试流程,具体的测试方法和步骤可能因您的项目和环境而有所不同。建议您参考 Seata 的官方文档和示例代码,以确保正确安装和配置 Seata,并正确测试分布式事务功能。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值