seata入门

分布式事务seata的使用

一、Seata 是什么

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。AT模式是阿里首推的模式,阿里云上有商用版本的GTS(Global Transaction Service 全局事务服务)

二、seata的三大角色

在 Seata 的架构中,一共有三个角色:

 TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。 

TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。

RM (Resource Manager) - 资源管理器 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。 

其中,TC 为单独部署的 Server 服务端,TM 和 RM 为嵌入到应用中的 Client 客户端。

1.TM 请求 TC 开启一个全局事务。TC 会生成一个 XID 作为该全局事务的编号。XID,会在微服务的调用链路中传播,保证将多个微服务 的子事务关联在一起。 

2.RM 请求 TC 将本地事务注册为全局事务的分支事务,通过全局事务的 XID 进行关联。 

3.TM 请求 TC 告诉 XID 对应的全局事务是进行提交还是回滚。 

4.TC 驱动 RM 们将 XID 对应的自己的本地事务进行提交还是回滚。

三、seata的使用

业务需求:模拟用户购买商品付钱,账户余额不足的情况下,数据进行回滚。

使用的是seata-server-1.3.0+nacos-server-2.0.0+mysql5.7+springboot2.2.6.RELEASE

seata官网:Seata

源码: https://github.com/seata/seata

首先下载seata-server

下载地址: 下载中心,选择seata-server-1.3.0版本(binary)进行下载

解压当前tar

我这边TC使用的是NACOS,别的我还没有研究。

启动NACOS服务,这里我没用集群,因为要开好几台机器,我就用的单机模式(nacos安装先自行百度一下,后面我争取补上)

启动mysql

因为需要nacos-config.sh和config.txt,将一些配置信息同步到nacos中,但是解压的包中没有这两个文件,所以要去github中下载这两个文件。登录seata的github,选择1.3.0分支

进入script/config-center/nacos下面下载nacos-config.sh

进入script/config-center/  下面下载config.txt

将nacos-config.sh放到解压的seata目录下,将config.txt文件放到seata目录的同层目录下

config.txt目录:

nacos-config.sh目录:

全局事务会话信息由3块内容构成,全局事务-->分支事务-->全局锁,对应表global_table、branch_table、lock_table 创建数据库seata。去到当前路径下载sql文件

连接mysql新建一个库,运行刚才下载的sql文件

然后再新建两个数据库,分别问seata_account和seata_order,然后创建业务表。

seata_account库,建表语句

CREATE TABLE `t_account` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',

  `user_id` bigint(20) DEFAULT NULL COMMENT '用户id',

  `total` decimal(10,0) DEFAULT NULL COMMENT '总额度',

  `used` decimal(10,0) DEFAULT NULL COMMENT '已用余额',

  `residue` decimal(10,0) DEFAULT '0' COMMENT '剩余可用额度',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

seata_order库,建表语句

CREATE TABLE `t_order` (

  `id` bigint(20) NOT NULL AUTO_INCREMENT,

  `user_id` bigint(20) DEFAULT NULL COMMENT '用户id',

  `product_id` bigint(20) DEFAULT NULL COMMENT '产品id',

  `count` int(11) DEFAULT NULL COMMENT '数量',

  `money` decimal(11,0) DEFAULT NULL COMMENT '金额',

  `status` int(11) DEFAULT NULL COMMENT '订单状态:0:未完成;1:已完结',

  PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

然后分别在两个库中创建undo_log(日志回滚表)

CREATE TABLE `undo_log` (

  `branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',

  `xid` varchar(128) 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 DEFAULT CHARSET=utf8;

最终两个库的样子:

数据库创建完毕后,我们开始修改seata的配置文件,去到seata的安装目录中,修改配置文件

先修改安装目录下conf目录下的registry.cof文件

将type改成nacos,然后配置nacos的地址,这里面cluster一般为default,看个人需求是否更改,如果更改成其他的值,还需要修改config.txt这个文件里面的属性,registry.cof里面的config属性也需要修改成nacos,并配置好nacos的连接属性

然后修改conf个目录下的file.conf

将mode改成db,然后配置mysql的连接属性,如果是mysql8,先去看看安装目录下lib/jdbc下面有没有相应的连接包,如果没有加上。然后修改driverClassName为com.mysql.cj.jdbc.Driver

然后修改和seata目录平行的config.txt文件(前面已经下过了,放到了对应的位置了)

1处的seata-order-seata-service-group可以随便取,但是要和springboot的yml中的tx-service-group的值对应上

2处的service.gy-seata.groupList中的gy-seata要和registry.cof中nacos配置的cluster对应上

3处将mode模式改成db

4处配置MYSQL的连接属性

以上都配置完毕后保存,退出

然后回到seata安装目录下运行nacos-config.sh

sh nacos‐config.sh ‐h 127.0.0.1 ‐p 8848 ‐g SEATA_GROUP

-h: host,默认值 localhost 

-p: port,默认值 8848 

-g: 配置分组,默认值为 'SEATA_GROUP' 

-t: 租户信息,对应 Nacos 的命名空间ID字段, 默认值为空

我不知道为什么我加上-t就会报错,把-t去掉就可以运行了,如果报找不到config.txt文件,看一下nacos-config.sh文件,看看他读的config.txt的路径

报错的地方可以先忽略掉。

最后去到Bin目录下启动seata服务

如果启动出现问题,可以看一下日志文件,文件位置已经打印出来了。

下面我们创建两个springboot的项目,然后模拟一下用户下单,查看用户余额的操作。

我github实在传不上去,只能使用百度网盘了,具体的代码可以下载这个

链接:百度网盘 请输入提取码

提取码:8d3d

springboot的yml配置文件如下:

具体使用,只需要在方法上加上@GlobalTransactional(name = "saveOrderInfo"),就可以了

我使用的时候遇到了一个问题,系统启动的时候报endpoint format should like ip:port这个错误,我跟进去看下,问题出在这里

问题出现这,取出来的clusterName的值为null,这样后面再根据这个去取就会拼成service.null.groupList,然后就会报错了。我跟进去看了下,他是去取配置文件中的值了

所以我在项目中的resources目录下增加了一个file.conf文件

然后file.conf文件内容为

这样运行就没有问题了。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值