-->
侧边栏壁纸
博主头像
断钩鱼 博主等级

行动起来,活在当下

  • 累计撰写 28 篇文章
  • 累计创建 34 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

Seata的使用 AT模式

halt
2022-03-18 / 0 评论 / 0 点赞 / 3152 阅读 / 0 字

分布式事务解决方案 Seata

官网: https://seata.io/

官方文档:https://seata.io/zh-cn/docs/overview/what-is-seata.html

Seata Server 搭建

官方文档:https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html

涉及文件:https://github.com/seata/seata/tree/1.4.0/script

  • client

存放client端sql脚本 (包含 undo_log表) ,参数配置

  • config-center

各个配置中心参数导入脚本,config.txt(包含server和client,原名nacos-config.txt)为通用参数文件

  • server

server端数据库脚本 (包含 lock_table、branch_table 与 global_table) 及各个容器配置

下载 Seata Server

地址:https://github.com/seata/seata/releases 根据版本下载

Seata 配置文件

官方文档:https://seata.io/zh-cn/docs/user/configurations.html

查看静态资源中的 \script\config-center\config.txt 文件,根据官方文档按需修改

  1. 修改 server 端 数据存储方式 为 mysql 修改驱动类名、连接信息和用户名密码

    store.db.dbType=mysql
    store.db.driverClassName=com.mysql.cj.jdbc.Driver
    store.db.url=jdbc:mysql://127.0.0.1:3306/seata_server?useUnicode=true&serverTimezone=GMT%2B8&rewriteBatchedStatements=true
    store.db.user=root
    store.db.password=root
    

Seata 事务分组

官方文档:https://seata.io/zh-cn/docs/user/txgroup/transaction-group.html

当一个事务组不可用时 可动态的切换到另一个事务组 保证 HA (高可用 )

使用方式

Server端配置

  1. 查看静态资源中的 \script\config-center\config.txt 文件 找到如下配置

    # service.vgroupMapping.{事务组名称}={事务组集群名称}
    service.vgroupMapping.my_test_tx_group=default
    # service.{事务组集群名称}.grouplist={SeataServer ip:port}
    service.default.grouplist=127.0.0.1:8091
    
  2. 将以上配置进行修改 事务组名称 & 集群名称可自定义

    service.vgroupMapping.default_tx_group=default
    service.default.grouplist=127.0.0.1:8091
    

Client 端配置

  1. 指定所使用的事务组名称即可

    这样 就可以通过配置中心的配置查找到事务组集群信息了

    seata:
      tx-service-group: default_tx_group
    

Seata Server 整合 Nacos

整合注册中心

  1. 修改 \seata-server-1.4.2\conf\registry.conf

    指定注册方式 注册中心地址 应用名称等

    registry {
      # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
      type = "nacos"
      nacos {
        application = "seata-server"
        serverAddr = "192.168.59.102:8848"
        group = "SEATA_GROUP"
        namespace = ""
        cluster = "default"
        username = ""
        password = ""
      }
    }
    

整合配置中心

  1. 修改 \seata-server-1.4.2\conf\registry.conf

    1.4.2 之前 指定配置存储方式 配置中心中心地址 分组 等 因为配置项较多 可以考虑使用单独的nacos 配置命名空间

    1.4.2开始,支持了使用一个配置文件取获取所有配置 只需要将 config.txt 中的配置复制到nacos配置中心即可 例如:seata.properties

    config {
      # file、nacos 、apollo、zk、consul、etcd3
      type = "nacos"
    
      nacos {
        serverAddr = "192.168.59.102:8848"
        namespace = ""
        group = "SEATA_GROUP"
        username = ""
        password = ""
        dataId = "seata.properties"
      }
    }
    

上传配置至Nacos配置中心

1.4.2 前的版本需要使用脚本上传配置 具体方法可到 https://seata.io/zh-cn/docs/user/configurations.html 查看

1.4.2开始在配置中心新建配置文件 并在配置中指定 dataId 即可

修改事务日志存放位置

如果 上面的配置存放位置为nacos则到nacos中修改 config.type= nacos

  1. 初始化数据库

    查看静态资源中的 \script\server\db\ 文件夹下的sql脚本,找到对应的sql脚本进行初始化

    mysql 脚本

    -- -------------------------------- The script used when storeMode is 'db' --------------------------------
    -- the table to store GlobalSession data
    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;
    
    -- the table to store BranchSession data
    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;
    
    -- the table to store lock data
    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;
    
    
  2. 修改 \seata-server-1.4.2\conf\file.conf

    只适用于 config.type= file
    指定存储方式以及存储配置

    store {
      ## store mode: file、db、redis
      mode = "db"
          ## database store property
      db {
        ## the implement of javax.sql.DataSource, such as DruidDataSource(druid)/BasicDataSource(dbcp)/HikariDataSource(hikari) etc.
        datasource = "druid"
        ## mysql/oracle/postgresql/h2/oceanbase etc.
        dbType = "mysql"
        driverClassName = "com.mysql.jdbc.Driver"
        ## if using mysql to store the data, recommend add rewriteBatchedStatements=true in jdbc connection param
        url = "jdbc:mysql://127.0.0.1:3306/seata_server?rewriteBatchedStatements=true"
        user = "root"
        password = "root"
        minConn = 5
        maxConn = 100
        globalTable = "global_table"
        branchTable = "branch_table"
        lockTable = "lock_table"
        queryLimit = 100
        maxWait = 5000
      }
    }
    

Seata AT模式的使用

官方文档:https://seata.io/zh-cn/docs/ops/deploy-guide-beginner.html

AT 模式介绍 :https://seata.io/zh-cn/docs/dev/mode/at-mode.html

AT模式同样基于 二阶段提交 2PC 数据回滚机制依靠 undo_log 表

数据库中添加 undo_log 表

静态资源目录 /script/client/at/db/ 脚本

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';

引入依赖

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

添加配置

seata:
  # 指定事务分组
  tx-service-group: default_tx_group
  # 指定SeataServer注册中心信息
  registry:
    type: nacos
    nacos:
      application: seata-server
      group: SEATA_GROUP
      server-addr: ${spring.cloud.nacos.config.server-addr}
  # 指定SeataServer配置中心信息
  config:
    type: nacos
    nacos:
      group: SEATA_GROUP
      server-addr: ${spring.cloud.nacos.config.server-addr}
      # 指定seata配置文件data id
      data-id: seata.properties

在事务发起方使用注解 @GlobalTransactional

其他事务分支使用 @Transactional 即可

  • 例如:

    /**
     * 点赞数据异步落库<br/>
     * 1.更新文章点赞数据(更新点赞数量) 远程调用 需要分布式事务<br/>
     * 2.更新评论点赞数据(更新点赞数量)<br/>
     * 3.更新回复点赞数据(更新点赞数量)<br/>
     * 4.更新点赞详情(点赞类型 数据等)<br/>
     */
    @GlobalTransactional
    @XxlJob("saveArticleLikedCount")
    public void saveArticleLikedCount() {
        .....
    }
    
0
博主关闭了所有页面的评论