Spring Cloud Alibaba 分布式事务 Seata 入门

本文介绍了Seata分布式事务的四种模式、三个基本组件及其生命周期,并详细阐述了Seata TC Server的安装过程,包括单机和集群部署。接着,文章通过实例展示了如何在AT模式下整合OpenFeign,搭建订单、仓储和账户服务,并进行了分布式事务的正常提交和异常回滚测试。最后提供了示例代码下载链接。
摘要由CSDN通过智能技术生成

1. Seata 简介
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。

seata官网地址

1.1 四种事务模式
Seata 将为用户提供 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
  • AT 模式:提供无侵入自动补偿的事务模式,详细可参考《Seata AT 模式》官方文档
  • TCC 模式:支持调用自定义的提交或者回滚的逻辑,详细可参考《Seata TCC 模式》官方文档
  • Saga 模式:为长事务提供有效的解决方案,详细可参考《Seata Saga 模式》官方文档
  • XA 模式:强一致性事务,拥有全局事务的隔离性,详细可参考《Seata XA 模式》官方文档
1.2 三个基本组件
seata由三个基本组件构成,如下图所示:

在这里插入图片描述

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚。
  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围,开始全局事务、提交或回滚全局事务。
  • RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
1.3 seata分布式事务的生命周期

在这里插入图片描述
1、TM请求TC开始一个新的全局事务,TC生成一个表示全局事务的XID。
2、XID通过微服务的调用链传播。
3、RM将本地事务注册为XID对应全局事务的分支到TC。
4、TM请求TC提交或回滚XID对应的全局事务。
5、TC驱动XID对应全局事务下的所有分支事务来完成分支提交或回滚。

2. Seata TC Server 安装
tc需要存储全局事务和分支事务的数据,目前有两种存储模式:
  • file模式:适合单机部署,全局事务和分支事务的数据持久化到本地文件。

  • db模式:适合集群部署,全局事务和分支事务的数据通过db进行共享。

2.1 单机部署

打开 seata下载页面,选择最新的版本下载

# 创建seata目录
$ mkdir -p /usr/seata
$ cd /usr/seata

# 下载
$ wget https://www.github.com//seata/seata/releases/download/v1.4.0/seata-server-1.4.0.tar.gz
# 解压文件
$ tar -zxvf seata-server-1.4.0.tar.gz

# 查看seata目录
$ cd seata
$ ll
总用量 48
drwxr-xr-x. 2  root root     53 1月  19 10:21 bin # 启动TC的shell脚本
drwxr-xr-x. 3  root root   141 11月  2 17:30 conf # 配置文件
drwxr-xr-x. 3  root root  8192 11月  2 17:30 lib # 依赖的jar包
-rw-r--r--. 1  root root 11365 5月  13 2019 LICENSE

# 后台启动 tc server 
$ nohup sh bin/seata-server.sh & 

# 查看nohup.out日志,出现Server started表示启动成功,默认端口是8091
$ tail -f nohup.out
1:21:52.477  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is registry
11:21:52.486  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is /usr/seata/seata/conf/registry.conf
11:21:53.094  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is file.conf
11:21:53.094  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is file.conf
11:22:05.452  INFO --- [                     main] i.s.core.rpc.netty.NettyServerBootstrap  : Server started, listen port: 8091

# 再次查看seata目录,发现多了nohup.out文件和sessionStore目录
$ ll
drwxr-xr-x. 2 root root     53 1月  19 10:21 bin
drwxr-xr-x. 3  root root   141 11月  2 17:30 conf
drwxr-xr-x. 3  root root  8192 11月  2 17:30 lib
-rw-r--r--. 1  root root 11365 5月  13 2019 LICENSE
-rw-------. 1 root root  32966 1月  19 11:22 nohup.out
drwxr-xr-x. 2 root root     23 1月  19 10:26 sessionStore

# 查看sessionStore目录,file模式下持久化的文件就是 root.data
$ cd sessionStore
$ ll
-rw-r--r--. 1 root root 0 1月  19 10:26 root.data
2.2 集群部署
多个seata tc server实例组成了tc集群,它们通过db实现了全局和分支事务数据共享,则拥有了高可用的能力。每一个tc server都可以注册自己到注册中心,方便微服务应用通过注册中心获取它们的连接地址。整体架构图如下所示:

在这里插入图片描述

1、使用 mysql.sql 脚本初始化TC Server 数据库,脚本内容如下:

-- -------------------------------- 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数据库,执行上述sql脚本,完成后的结果如下图所示:

在这里插入图片描述

3、修改 conf/file.conf 配置文件,设置为db模式,内容如下所示:
## transaction log store, only used in seata-server
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.cj.jdbc.Driver"
    url = "jdbc:mysql://192.168.0.118:3306/seata?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8"
    user = "root"
    password = "123456"
    minConn = 5
    maxConn = 100
    globalTable = "global_table"
    branchTable = "branch_table"
    lockTable = "lock_table"
    queryLimit = 100
    maxWait = 5000
  }
}
service {
   
  vgroupMapping.my_test_tx_group = "seata-tc-server"
}
4、修改 conf/registry.conf 配置文件,设置使用Eureka注册中心,application表示TC Server 注册到eureka显示的服务名称。
registry {
   
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "eureka"
  loadBalance = "RandomLoadBalance"
  loadBalanceVirtualNodes = 10

  eureka {
   
    serviceUrl = "http://192.168.0.118:8761/eureka"
    application = "seata-tc-server"
    weight = "1"
  }
}

5、指定端口号、节点编号启动TC Server,先后执行如下shell命令启动两个节点
# 启动第一个tc server节点
$ nohup sh bin/seata-server.sh -p 18090 -n 1 &

# 启动第二个tc server节点
$ nohup sh bin/seata-server.sh -p 28090 -n 2 &
打印 nohup.out 文件里面的日志
$ tail -f nohup.out 
14:23:49.581  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is registry
14:23:49.623  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is /usr/seata/seata/conf/registry.conf
14:23:52.019  INFO --- [                     main] io.seata.config.FileConfiguration        : The file name of the operation is file.conf
14:23:52.027  INFO --- [                     main] io.seata.config.FileConfiguration        : The configuration file used is file.conf
# 初始化连接池
14:24:06.970  INFO --- [                     main] com.alibaba.druid.pool.DruidDataSource   : {
   dataSource-1} inited  
# 节点启动成功
14:24:11.591  INFO --- [                     main] i.s.core.rpc.netty.NettyServerBootstrap  : Server started, listen port: 28090
......
# 注册中心连接成功
14:24:42.806  INFO --- [                     main] com.netflix.discovery.DiscoveryClient    : Discovery Client initialized at timestamp 1611037482804 with initial instances count: 1
14:24:42.807  INFO --- [                     main] com.netflix.discovery.DiscoveryClient    : Saw local status change event StatusChangeEvent [
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值