Seata安装配置及常见问题

官方文档

Nacos 致力于帮助您发现、配置和管理微服务。

10、Seata-server安装配置

# 方式一:Docker部署seata-server
# 参考《56、Docker安装软件》-

90、Seata-server-1.4.2、Nacos-1.4.2整合MySQL作为事务会话存储

采用AT模式实现分布式事务

第一步:

Docker启动seata-server,参考Docker部署seata-server

参考seata-server源代码包中,script/client/conf目录,给seata-server配置nacos配置中心

/data/docker/seata-server/config/registry.conf

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    application = "seata-server"
    serverAddr = "10.10.225.117:8848"
    group = "SEATA_GROUP"
    namespace = ""
    cluster = "default"
    username = "nacos"
    password = "nacos"
  }
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"

  nacos {
    serverAddr = "10.10.225.117:8848"
    namespace = ""
    group = "SEATA_GROUP"
    username = "nacos"
    password = "nacos"
    dataId = "seataServer.properties"
  }
}

第二步:

参考seata-server源代码包中,script/config-center目录,给seata-server配置mysql数据库

1、编辑config.txt文件

service.vgroupMapping.my_test_tx_group=default
service.disableGlobalTransaction=false
store.mode=db
store.db.datasource=druid
store.db.dbType=mysql
store.db.driverClassName=com.mysql.jdbc.Driver
store.db.url=jdbc:mysql://10.10.225.117:3306/seata?useUnicode=true
store.db.user=root
store.db.password=password
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

2、执行script/config-center/nacos/nacos-config.sh将数据库配置写入到nacos配置中心,如果有需要更改,可直接通过控制台更改

sh nacos-config.sh -h 10.10.225.117

3、访问nacos配置中心,查看配置

第三步:

1.在参与全局事务的服务项目数据库中加入undo_log这张表

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

2.在mysql数据库中创建名为seata的库,并使用以下下sql

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

第四步:

引入seata依赖

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

修改application.yml配置文件

seata:
  enabled: true
  application-id: applicationName
  tx-service-group: my_test_tx_group
  enable-auto-data-source-proxy: true
  config:
    type: nacos
    nacos:
      namespace:
      serverAddr: 10.10.225.117:8848
      group: SEATA_GROUP
      username: "nacos"
      password: "nacos"
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 10.10.225.117:8848
      group: SEATA_GROUP
      namespace:
      username: "nacos"
      password: "nacos"

第五步:

在全局事务调用者(发起全局事务的服务)的接口上加入@GlobalTransactional

第六步:

搭建seata-server高可用集群,启动两个seata-server即可

91、Redis作为事务会话存储

替换上述第二步编辑config.txt文件

store.mode=redisstore.redis.host=10.10.225.117store.redis.port=6379store.redis.maxConn=10store.redis.minConn=1store.redis.database=0store.redis.password=passwordstore.redis.queryLimit=100

运行仓库中提供的nacos脚本,将以上信息提交到nacos控制台,如果有需要更改,可直接通过控制台更改

就这么简单,无需像db模式需要建立3张表,直接可用.

服务自检,自动升降级

流程介绍:

未命名文件

以上是整个升降级原理流程.

原理解析:

通过服务自检线程+TM的异常,来判断是否当前是由于seata自身出现问题,导致事务异常,如果是的话,连续错误数达到了用户设置的阈值那么当前会直接关闭全局事务,让用户接口可以正常的响应,而不被Seata的异常所影响.

恢复全局事务就是反之了,当前如果是关闭时,自检线程会模拟事务的begin跟commit,如果是正常且连续正常达到阈值,那么就会恢复全局事务的管理,保证事务一致性.

其实这个功能的作用就是尽最大可能保证Seata出现问题的时候,去不影响用户,且服务恢复后,第一时间再继续为用户保驾护航.

总结:

用的放心,用的舒心.

XA模式介绍与上手

注:XA相关内容大部分来自于Seata发起人之一: 煊檍,GitHub ID:sharajava 特此感谢

前提:

如何确认我是否可以使用XA模式?

  • 支持XA 事务的数据库。
  • Java 应用,通过 JDBC 访问数据库。

整体机制

在 Seata 定义的分布式事务框架内,利用事务资源(数据库、消息服务等)对 XA 协议的支持,以 XA 协议的机制来管理分支事务的一种 事务模式。

img
  • 执行阶段:
    • 可回滚:业务 SQL 操作放在 XA 分支中进行,由资源对 XA 协议的支持来保证 可回滚
    • 持久化:XA 分支完成后,执行 XA prepare,同样,由资源对 XA 协议的支持来保证 持久化(即,之后任何意外都不会造成无法回滚的情况)
  • 完成阶段:
    • 分支提交:执行 XA 分支的 commit
    • 分支回滚:执行 XA 分支的 rollback

接下来我们AT 模式

at-mod
  • 执行阶段:
    • 可回滚:根据 SQL 解析结果,记录回滚日志
    • 持久化:回滚日志和业务 SQL 在同一个本地事务中提交到数据库
  • 完成阶段:
    • 分支提交:异步删除回滚日志记录
    • 分支回滚:依据回滚日志进行反向补偿更新

对比:

通过以上的区别,其实我们可以发现,其实XA流程相对AT模式,是简单许多.

AT: 解析sql生成undolog+竞争全局锁(rpc)

XA: 支持xa的数据库即可

无侵入式 XA>AT 性能,事务链路不出现异常情况下,由于AT一阶段预先提交,以及锁由TC一侧统一管理,理论上AT的性能要高于XA.

但如果涉及到rollback时,由于AT还需要去读取undolog,镜像校验,回滚数据等步骤.个人认为在rollback时.XA是要高于AT

注:不支持AT+XA的一个事务.无法保证隔离性

如果你用的是Redis+XA这样的配置,那么你等于主需要在发起事务的方法或接口上加入全局事务注解.

常见问题解析

1.事务分组配置如何正确理解

首先我们要明确的是事务分组配置存在于client端

示例

seata:  tx-service-group: test

那么以上信息仅代表我的事务分组为test

而client端与server的服务发现基于通过事务分组所对应的server集群名,来做服务发现.

所以我们必须把我们的事务分组对应的那个server集群给提交到nacos,以便于我们可以及时发现,和及时切换集群

service.vgroupMapping.test=default

上面的示例解读:我的事务分组名为test所对应的server集群名叫default

所以我们的client端会去通过这个default集群去找到对应可用的server服务

2.服务熔断或者参与方做了全局异常捕获后,事务回滚的几种方式介绍与示例

方式一:

通过result code 来做手动api回滚

方式二:

通过result code 抛出异常触发回滚

方式三:

服务熔断实现内直接抛出异常

方式四:

服务熔断内api触发回滚

欢迎更多方式补充......

3.如何使用保证捕获异常后还可以回滚事务

方式一:

使用api方式回滚事务

方式二:

全局异常捕获器位于全局事务的外层

4.分布式事务带来的性能降低,优化方式.

异步化当前全局事务整体调用链,缓存对应的事务状态

前端通过轮询来得到结果

请稍后...

10s 倒计时

已完成

欢迎更多补充........

如何参与到Seata的源码贡献呢?

1.首先fork Seata的仓库

2.拉取官方的develop作为基础

3.创建自己的分支,进行代码编写并提交到这个分支

5.提交这个分支到官方仓库的develop分支

6.等待review,及时响应,及时根据建议修改自己的代码逻辑

7.恭喜你成为Seata的Contributor

更加详细的参与到Seata贡献的指导请访问: https://github.com/seata/seata/blob/develop/CONTRIBUTING.md

待认领的任务列表

1.Redis的事务会话模式结构优化

2.Redis作为undolog 二级缓存

3.更多数据库的支持

4.AT模式oracle的多语句支持

5.支持Raft的高可用Seata-Servier集群

6.XA模式mysql 8.0.11以上驱动支持

7.消息队列分布式事务

8.Seata-Server 改造为Spring Boot

9.Redis String结构换为Hash结构

还有更多可以从issues,官方交流群等区域进行沟通交流时发现.

Q.E.D.


行走在天地间自由的灵魂