• 微服务集成seata完成分布式事务,解决数据不一致问题


    细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性

    我们可以选择seata来进行分布式事务杜绝这种现象的发生

    seata官网:https://seata.io/zh-cn/docs/overview/what-is-seata.html

    之前的教程:https://www.cnblogs.com/leafstar/p/17641407.html

    教程总地址在文末

    1.我使用的是seata1.7版本,可以从官网很简单下载到,不同版本配置可能略有不同

    2.修改seata配置conf/application.yml

    我的配置如下:

    复制代码
    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:
      # nacos配置
      config:
        type: nacos
        nacos:
          server-addr: 127.0.0.1:8848
          namespace:
          group: SEATA_GROUP
          username:
          password:
          context-path:
          data-id: seataServer.properties
          ##if use MSE Nacos with auth, mutex with username/password attribute
          #access-key:
          #secret-key:
      registry:
        # nacos配置
        type: nacos
        nacos:
          application: seata-server
          server-addr: 127.0.0.1:8848
          group: SEATA_GROUP
          namespace:
          cluster: default
          username:
          password:
          context-path:
          ##if use MSE Nacos with auth, mutex with username/password attribute
          #access-key:
          #secret-key:
    #  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,/**/*.jpeg,/**/*.ico,/api/v1/auth/login
    复制代码

    3.通过bin目录下的脚本启动seata

    4.在需要发起全局事务的数据库中创建undo_log表,语句如下

    复制代码
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;
    
    -- ----------------------------
    -- Table structure for undo_log
    -- ----------------------------
    DROP TABLE IF EXISTS `undo_log`;
    CREATE TABLE `undo_log`  (
      `id` bigint NOT NULL AUTO_INCREMENT,
      `branch_id` bigint NOT NULL,
      `xid` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
      `context` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
      `rollback_info` longblob NOT NULL,
      `log_status` int NOT NULL,
      `log_created` datetime NOT NULL,
      `log_modified` datetime NOT NULL,
      `ext` varchar(100) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE,
      UNIQUE INDEX `ux_undo_log`(`xid` ASC, `branch_id` ASC) USING BTREE
    ) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8mb3 COLLATE = utf8mb3_general_ci ROW_FORMAT = Dynamic;
    
    -- ----------------------------
    -- Records of undo_log
    -- ----------------------------
    
    SET FOREIGN_KEY_CHECKS = 1;
    复制代码

    将seata目录下seata\script\server\db的mysql.sql脚本文件导入数据库中,最终效果如下

     

    5.仅在需要发起全局事务的服务中添加依赖

    
        io.seata
        seata-spring-boot-starter
        1.4.2
     

    6.仅在需要发起全局事务的服务中添加以下配置即可

    复制代码
    seata:
      enabled: true
      application-id: ccxi-abc
      tx-service-group: ccxi_tx_group
      service:
        vgroup-mapping:
          ccxi_tx_group: default
      registry:
        type: nacos
        nacos:
          server-addr: 127.0.0.1:8848
          namespace: public
          group: SEATA_GROUP
          application: seata-server
    复制代码

    7.在nacos中添加seataServer.properties配置如下图

    配置如下

    复制代码
    #Transaction storage configuration, only for the server.
    store.mode=db
    store.lock.mode=db
    store.session.mode=db
    
    #These configurations are required if the `store mode` is `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/bank1?useSSL=false&useUnicode=true&rewriteBatchedStatements=true
    store.db.user=root
    store.db.password=123456
    store.db.minConn=5
    store.db.maxConn=30
    store.db.globalTable=global_table
    store.db.branchTable=branch_table
    store.db.distributedLockTable=distributed_lock
    store.db.queryLimit=100
    store.db.lockTable=lock_table
    store.db.maxWait=5000
    复制代码

    将数据库信息改成自己的信息

    8.在准备开启全局事务的接口下添加注解

     9.报错如下,execute executeAutoCommitTrue error:[xid:192.168.74.1:8091:8413149769213006417]get table meta failed, please check whether the table `account` exists.

    主要是因为数据表中没有设置主键,在此为了简单,我们选择将name变成主键

    10.重启项目并调用转账接口,可以看到seata的服务面板显示如下

     11现在我们来模拟小红收款异常,故意在这里抛出异常并等待20秒,重启服务

     

    12.调用转账接口

    可以看到,undo_log已经被写入一条数据,抛出异常后,这条数据就没了,同时我们对小明的转账修改也被撤销

    13.等待的20秒内,小明数据被修改

    抛出异常后,小明的数据又被改回来了

     14.seata控制台显示回滚成功

     15.至此,我们完成了分布式事务的简单使用,这个系列的实战教程也就结束了

     16.教程列表如下

    1.SpringBoot+Mybatis-Plus+Mysql的保姆级搭建

    https://www.cnblogs.com/leafstar/p/17638741.html

    2.Mybatis-Plus+Nacos配置中心和服务发现保姆级教程

    https://www.cnblogs.com/leafstar/p/17638782.html

    3.Mybatis-Plus+Nacos+Dubbo进行远程RPC调用保姆级教程

    https://www.cnblogs.com/leafstar/p/17638933.html

    4.微服务集成redis并通过redis实现排行榜的功能

    https://www.cnblogs.com/leafstar/p/17641358.html

    5.微服务集成RabbitMq保姆级教程

    https://www.cnblogs.com/leafstar/p/17641407.html

    6.微服务集成seata完成分布式事务,解决数据不一致问题

    https://www.cnblogs.com/leafstar/p/17641498.html

     源码:https://gitee.com/leafstart/spring-cloud-bank.git

     

  • 相关阅读:
    五金机电行业经销商协同管理系统解决方案
    亚马逊鲲鹏系统六大优势
    [微前端实战]---023系统重构
    数据挖掘十大算法--Apriori算法
    SpringBoot 项目实战 ~ 5.菜品管理
    计算机毕业设计之交互式大学英语学习平台
    css 对号 叉号
    【C++编程语言】STL常用算法 算术生成和集合算法
    深入解析Flutter下一代渲染引擎Impeller
    51.【结构体初始化的两种方法】
  • 原文地址:https://www.cnblogs.com/leafstar/p/17641498.html