SEATA1.6.1的配置与使用

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: SEATA1.6.1的配置与使用

说在前面

本文基于seata1.6.1 AT模式,以nacos作为配置、注册中心。本篇我们先使用,正确使用后再看下一篇相关概念和原理,这样可以掌握的更透彻。

1、seata服务的安装与配置

下载seata-server:https://seata.io/zh-cn/blog/download.html

解压后找到conf目录下的application.yml文件,从示例文件中找我们需要的配置复制到application.yml

温馨提示:复制以下代码注意修改【namespace】【data-id】【url】【user】【password

server:
  port: 7091
spring:
  application:
    name: seata-server
logging:
  config: classpath:logback-spring.xml
  file:
    path: ${user.home}/logs/seata
  extend:
    logstash-appender:
      destination: 127.0.0.1:4560
    kafka-appender:
      bootstrap-servers: 127.0.0.1:9092
      topic: logback_to_logstash
console:
  user:
    username: seata
    password: seata
seata:
  config:
    # support: nacos 、 consul 、 apollo 、 zk  、 etcd3
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: 434e7801-0b5d-4fd2-b96a-acbac849fd84
      group: SEATA_GROUP
      username:
      password:
      context-path:
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key:
      #secret-key:
      data-id: seataServer.properties
  registry:
    # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa
    type: nacos
    preferred-networks: 30.240.*
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace: 434e7801-0b5d-4fd2-b96a-acbac849fd84
      cluster: default
      username:
      password:
      context-path:
      ##if use MSE Nacos with auth, mutex with username/password attribute
      #access-key:
      #secret-key:
  store:
    # support: file 、 db 、 redis
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=GMT
      user: root
      password: 1234
      min-conn: 10
      max-conn: 100
      global-table: global_table
      branch-table: branch_table
      lock-table: lock_table
      distributed-lock-table: distributed_lock
      query-limit: 1000
      max-wait: 5000  
#  server:
#    service-port: 8091 #If not configured, the default is '${server.port} + 1000'
  security:
    secretKey: SeataSecretKey0c382ef121d778043159209298fd40bf3850a017
    tokenValidityInMilliseconds: 1800000
    ignore:
      urls: /,/**/*.css,/**/*.js,/**/*.html,/**/*.map,/**/*.svg,/**/*.png,/**/*.ico,/console-fe/public/**,/api/v1/auth/login

此时我们去nacos中新建一个配置,这里的Data ID就是上述配置中需要的。

配置文件的内容:【注意修改url、user、password】

#Transaction routing rules configuration, only for the client
service.vgroupMapping.default_tx_group=default
service.default.grouplist=127.0.0.1:8091
# 数据存储方式,db代表数据库
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.cj.jdbc.Driver
store.db.url=jdbc:mysql://127.0.0.1:3306/seata?useUnicode=true&rewriteBatchedStatements=true&serverTimezone=GMT
store.db.user=root
store.db.password=1234
store.db.minConn=5
store.db.maxConn=30
store.db.globalTable=global_table
store.db.branchTable=branch_table
store.db.queryLimit=100
store.db.lockTable=lock_table
store.db.maxWait=5000
# 事务、日志等配置
server.recovery.committingRetryPeriod=3000
server.recovery.asynCommittingRetryPeriod=3000
server.recovery.rollbackingRetryPeriod=3000
server.recovery.timeoutRetryPeriod=3000
server.maxCommitRetryTimeout=-1
server.maxRollbackRetryTimeout=-1
server.rollbackRetryTimeoutUnlockEnable=false
server.undo.logSaveDays=7
server.undo.logDeletePeriod=86400000
# 客户端与服务端传输方式
transport.serialization=seata
transport.compressor=none
# 关闭metrics功能,提高性能
metrics.enabled=false
metrics.registryType=compact
metrics.exporterList=prometheus
metrics.exporterPrometheusPort=9898

注意【service.vgroupMapping.default_tx_group=default】,后续需要使用。

我这里是用的windows,直接去bin目录下双击seata-server.bat

之后去nacos看一下,有健康实例就说明seata服务注册成功了。

2、使用seata

首先是sql脚本,在seata服务目录的\script\server\db下找到mysql的脚本执行一下

除此之外,我们还需要一个undo_log表

SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS =0;-- ------------------------------ Table structure for undo_log-- ----------------------------DROPTABLE IF EXISTS `undo_log`;CREATETABLE `undo_log`  (  `id` bigint(20)NOTNULL AUTO_INCREMENT,  `branch_id` bigint(20)NOTNULL,  `xid` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci NOTNULL,  `context` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NOTNULL,  `rollback_info` longblobNOTNULL,  `log_status` int(11)NOTNULL,  `log_created` datetimeNOTNULL,  `log_modified` datetimeNOTNULL,  PRIMARY KEY (`id`) USING BTREE,  UNIQUE INDEX `ux_undo_log`(`xid`, `branch_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT =12 CHARACTER SET= utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS =1;

以及我们的两张业务表

SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS =0;-- ------------------------------ Table structure for sys_order-- ----------------------------DROPTABLE IF EXISTS `sys_order`;CREATETABLE `sys_order`  (  `id` bigint(20)UNSIGNEDNOTNULL,  `product_id` bigint(20)UNSIGNEDNULL DEFAULT NULL,  `number` int(10)UNSIGNEDNULL DEFAULT NULL,  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET= utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS =1;SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS =0;-- ------------------------------ Table structure for sys_stock-- ----------------------------DROPTABLE IF EXISTS `sys_stock`;CREATETABLE `sys_stock`  (  `id` bigint(20)UNSIGNEDNOTNULL,  `product_id` bigint(20)UNSIGNEDNULL DEFAULT NULL,  `number` int(10)UNSIGNEDNULL DEFAULT NULL,  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET= utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;-- ------------------------------ Records of sys_stock-- ----------------------------INSERTINTO `sys_stock` VALUES(1629394254497902593,1629394038201819138,10);SET FOREIGN_KEY_CHECKS =1;

然后创建一个订单服务、一个库存服务,两个服务的pom依赖引入一致,我这里springboot版本号是2.2.5.RELEASE

<!-- nacos-discovery --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2.2.1.RELEASE</version></dependency><!-- nacos-config --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId><version>2.2.1.RELEASE</version></dependency><!-- org.springframework.cloud/spring-cloud-starter-openfeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.2.RELEASE</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.2</version></dependency><!-- mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version><scope>provided</scope></dependency><!-- seata-spring-boot-starter --><dependency><groupId>io.seata</groupId><artifactId>seata-spring-boot-starter</artifactId><version>1.6.1</version></dependency><!-- druid-spring-boot-starter --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency>

库存项目代码:properties  相关的值自己改一下。

spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.namespace=434e7801-0b5d-4fd2-b96a-acbac849fd84
spring.cloud.nacos.discovery.group=SEATA_GROUP
spring.application.name=sparrow-stock
server.port=8082
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=1234
##要和seataServer.properties中的保持一致seata.tx-service-group=default_tx_group
seata.service.vgroup-mapping.default_tx_group=default

//-----------controller

@RestController@RequestMapping("/stock")
publicclassStockController {
@AutowiredprivateStockServicestockService;
@PostMapping("/minus")
publicStringminus(@RequestParam("productId") LongproductId){
returnstockService.minus(productId);
    }
}


//---------entity

@TableName("sys_stock")
@DatapublicclassStock {
@TableIdprivateLongid;
@TableField("product_id")
privateLongproductId;
@TableField("number")
privateIntegernumber;
}

//------------service

publicinterfaceStockServiceextendsIService<Stock> {
Stringminus(LongproductId);
}

//-------------impl

@Service("stockService")
publicclassStockServiceImplextendsServiceImpl<StockMapper, Stock>implementsStockService {
@AutowiredprivateStockMapperstockMapper;
@OverridepublicStringminus(LongproductId) {
//int a =1/0;System.out.println("----------"+RootContext.getXID());
stockMapper.minus(productId);
return"库存-1";
    }
}

//-------------mapper

@MapperpublicinterfaceStockMapperextendsBaseMapper<Stock> {
@Update("update sys_stock set number=number-1 where product_id=#{productId}")
Integerminus(LongproductId);
}


订单服务代码:

spring.cloud.nacos.discovery.server-addr=localhost:8848
spring.cloud.nacos.discovery.namespace=434e7801-0b5d-4fd2-b96a-acbac849fd84
spring.cloud.nacos.discovery.group=SEATA_GROUP
spring.application.name=sparrow-order
server.port=8083
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=1234
##要和seataServer.properties中的保持一致seata.tx-service-group=default_tx_group
seata.service.vgroup-mapping.default_tx_group=default

//--------------Controller

@RestControllerpublicclassOrderController {
@AutowiredprivateOrderServiceorderService;
@GlobalTransactional@PostMapping("/add")
publicStringadd(LongproductId){
returnorderService.add(productId);
    }
}

//--------------entity

@TableName("sys_order")
@DatapublicclassOrder {
@TableIdprivateLongid;
@TableField("product_id")
privateLongproductId;
@TableField("number")
privateIntegernumber;
}

//-----------feign

@FeignClient(value="sparrow-stock",path="/stock")
publicinterfaceStockService {
@PostMapping("/minus")
Stringminus(@RequestParam("productId")LongproductId);
}

//----------service

publicinterfaceOrderServiceextendsIService<Order> {
Stringadd(LongproductId);
}

//-----------impl

@Service("orderService")
publicclassOrderServiceImplextendsServiceImpl<OrderMapper, Order>implementsOrderService {
@AutowiredprivateStockServicestockService;
@OverridepublicStringadd(LongproductId) {
System.out.println("----------"+RootContext.getXID());
//减库存stockService.minus(productId);
Orderorder=newOrder();
order.setId(IdWorker.getId());
order.setProductId(productId);
order.setNumber(1);
this.save(order);
inta=1/0;
return"商品下单成功";
    }
}


//-------------mapper

@MapperpublicinterfaceOrderMapperextendsBaseMapper<Order> {
}


先演示不用seata,使用spring事务注解@Transactional

两种情况:1、本地服务代码先执行,然后再调远程服务接口,比如我在减库存的时候失败了,其实两边数据都会回滚

2、调用远程服务接口后,还需要执行本地服务的业务代码。比如先减库存成功了,但是订单服务这边还需要执行其他业务,但是这些业务失败了,那么订单这里会回滚数据,库存服务那边就没法回滚了。这里为了方便演示,我把库存业务放到前面去,结果就是库存减成功了,而订单服务这边数据回滚了。

使用seata的@GlobalTransactional 在本地服务的controller上加。

再次调用接口,库存表中的数量没有减少

想看undo_log表中数据是临时数据,想看的话可以debug。至此,配置与使用篇完结。下一篇我们看看seata的相关概念和实现原理。

相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
自然语言处理 监控 Dubbo
Seata常见问题之使用tcc模式配置yml如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
101 4
|
11月前
|
SpringCloudAlibaba NoSQL Java
Seata配置参考
SeataClient是直接集成到我们的业务微服务中,SeataClient的原理是代理我们jdbc数据源,在应用程序和数据库之间加了一层,通过添加的这一层来做事务管理。
385 0
|
1月前
|
NoSQL Nacos Redis
Seata 配置
Seata
73 2
|
1月前
|
SQL 关系型数据库 MySQL
【Seata1.5.2 下载 & 配置 & 整合 & 踩坑 & 测试】—— 含各种踩坑记录(详细版)(上)
【Seata1.5.2 下载 & 配置 & 整合 & 踩坑 & 测试】—— 含各种踩坑记录(详细版)
427 0
|
1月前
|
存储 关系型数据库 MySQL
Seata常见问题之程序读的nocas的配置如何解决
Seata 是一个开源的分布式事务解决方案,旨在提供高效且简单的事务协调机制,以解决微服务架构下跨服务调用(分布式场景)的一致性问题。以下是Seata常见问题的一个合集
|
1月前
|
Shell 测试技术 Linux
单节点Seata支持多环境配置隔离,允许你独立配置不同环境的参数。
单节点Seata支持多环境配置隔离,允许你独立配置不同环境的参数。
47 1
|
1月前
|
SQL Java 数据库
【Seata1.5.2 下载 & 配置 & 整合 & 踩坑 & 测试】—— 含各种踩坑记录(详细版)(下)
【Seata1.5.2 下载 & 配置 & 整合 & 踩坑 & 测试】—— 含各种踩坑记录(详细版)(下)
165 0
|
1月前
|
中间件 关系型数据库 MySQL
Windows 安装 Seata 1.6.1 并配置开机自启
Windows 安装 Seata 1.6.1 并配置开机自启
|
9月前
|
弹性计算 Java Nacos
Spring Cloud Alibaba Seata 配置
Spring Cloud Alibaba Seata 配置
|
缓存 Java Nacos
Seata 动态配置订阅与降级实现原理
Seata 的动态降级需要结合配置中心的动态配置订阅功能。动态配置订阅,即通过配置中心监听订阅,根据需要读取已更新的缓存值,ZK、Apollo、Nacos 等第三方配置中心都有现成的监听器可实现动态刷新配置;动态降级,即通过动态更新指定配置参数值,使得 Seata 能够在运行过程中动态控制全局事务失效(目前只有 AT 模式有这个功能)。 那么 Seata 支持的多个配置中心是如何适配不同的动态配置订阅以及如何实现降级的呢?下面从源码的层面详细给大家讲解一番。
211 0
Seata 动态配置订阅与降级实现原理