在微服务系统中,分布式事务是我们必须要面临和解决的问题!!!
下图中的例子可以很好的解释分布式事务问题出现的场景:

图中问题的产生就在于更新库存数量是1个单独的事务,不受下订单方法所在事务的控制,更新库存数量方法执行之后,数量就已经持久化到数据库,后续的保存订单操作若出现异常也和它无关。这符合事务的隔离性和持久性的特性。事务的另外2个特性:原子性和一致性。
针对上述问题,目前比较主流的技术就是阿里巴巴推出的开源分布式事务解决方案Seata。
根据Seata官网的描述:Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
从官网上截取的一个关于Seata如何处理分布式事务的图:

Seata术语解释:
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
通俗理解:统筹协调各个分支事务的全局事务管理者,这个必须要另外启动一个seata的服务端。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
通俗理解:一般是分布式事务的发起方。需要我们在微服务端进行Seata的配置。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
通俗理解:RM一般是事务的参与者,也就是各个分支事务。需要我们在微服务进行Seata的配置
Seata Client - Seata客户端
每个引入了Seata依赖的微服务都称之为Seata客户端
Seata Server - Seata服务端*
Seata服务端也是一个微服务,需要注册到注册中心(一般是nacos)作为分布式事务的全局管理者,对分布式事务进行协调和处理。
注意:针对于Seata的理论部分,这里不做过多说明,本文只是交给大家如何使用,理论部分可去Seata官网或者去B站看看相关视频即可有一定的理解。
问题:如何使用Seata处理分布式事务问题?
这里我们下载2个文件夹
seata-1.3.0下载地址:https://github.com/seata/seata
将Seata项目以zip压缩包的形式下载。

下载及解压后如下图:

说明:为什么要下载上述文件夹?
因为如果只下载seata-server项目的话,初始化的sql脚本自1.0版本之后不在随项目提供,另外关于seata的客户端配置也没有提供。缺失的文件都在上面下载的文件夹的script目录中,因此我们有必要将其下载。
我们主要使用script,这里主要介绍script文件夹下的内容:

2. Seata server微服务seata下载
下载地址:https://github.com/seata/seata/releases

下载之后解压:

由于启动seta-server端服务需要提前配置或修改一些配置文件,比如要上传到nacos的seata客户端的配置,seata数据库的建表语句等。因此我们才在2.1.1中将这些文件事先下载。
在mysql数据库中创建一个数据库seata:

使用数据库管理工具执行目录C:\software\seata-1.3.0\script\server\db(不同电脑存放路径不同)下的mysql.sqlsql文件。

这样的话,Seata相关的数据库和表就准备好了。
注意:如果数据库的名称不是seata,那么后面对应的配置文件中关于数据库的连接的配置也要对应修改!
由于seata服务端的默认配置是以file文件的形式存储分布式事务中的信息的 。我们想要以数据库的存储方式来替换掉,因此需要修改相关配置文件。
打开目录C:\software\seata\conf(不同电脑存放路径不同):


在2.3.2中我们配置了连接nacos配置中心,要将seata关于客户端的配置上传到nacos配置中心,那么配置文件呢?需不需要修改呢?
打开目录C:\software\seata-1.3.0\script\config-center(不同电脑存放路径不同):

config.txt中的内容都是以键值对的形式存储的seata关于客户端的配置信息。在1.0版本之前键以-隔开每个单词如:vgroup-mapping,1.0的版本以驼峰命名法命名如:vgroupMapping。修改文件config.txt:

更正:上图中的.yml/yalm/application 更改为:yml/yaml/properties!!!
接下来我们使用命令将config.txt中的配置上传到nacos配置中心。打开目录C:\software\seata-1.3.0\script\config-center\nacos(不同电脑存放路径不同):

.sh结尾的文件是linux脚本命令,这里我们使用的windows系统,需要安装git才可以执行该命令。
git下载地址:https://git-scm.com/downloads
在·nacos-config.sh·所在目录打开git命令窗口,执行以下命令:

参数说明:
-h nacos所在主机地址。如:127.0.0.1;
-p nacos端口号。如:8848;
-t 命名空间。如:ae5104ef-bb91-467f-b1f4-c93f3b4ab326。
-g 分组组名。 如:DEFAULT_GROUP;
可根据需要进行添加。添加前要对照registry.conf中关于config下的配置,要和里面的配置保持一致。否则配置信息上传到不同的命名空间和分组,会导致后面使用seata客户端拉取不到对应的配置信息。
执行命令后,若出现以下内容:

表明配置信息已经上传到nacos配置中心,此时可以查看nacos界面:

启动客户端很简单。进入目录C:\software\seata\bin(不同电脑路径不同):

在该目录打开cmd命令窗口win+R输入以下内容:

出现以下内容:

seata服务端启动成功,默认端口8091。此时查看nacos的服务:

本次引入的seata的版本是1.3.0。
com.alibaba.cloud spring-cloud-starter-alibaba-seata seata-spring-boot-starter io.seata
io.seata seata-spring-boot-starter 1.3.0
在使用分布式事务的微服务端的配置文件.yml/.yaml/.properties中配置如下:
spring:cloud:alibaba:seata:# 自定义事务组的名称:这里自定的事务组名称为xgwms_inventory_tx_grouptx-service-group: xgwms_inventory_tx_group
seata:enabled: true# 哪个微服务要使用分布式事务application-id: ${spring.application.name}# 分布式事务组组名tx-service-group: xgwms_inventory_tx_groupenable-auto-data-source-proxy: trueregistry:type: nacosnacos:application: seata-server# nacos注册中心地址server-addr: 120.26.0.43:8848# 注册到哪个命名空间,默认为publicnamespace: ae5104ef-bb91-467f-b1f4-c93f3b4ab326# nacos服务所在分组组名group: DEFAULT_GROUPusername: nacospassword: nacosconfig:type: nacosnacos:# namcos配置中心地址serverAddr: 120.26.0.43:8848# 哪个命名空间的配置,默认为publicnamespace: ae5104ef-bb91-467f-b1f4-c93f3b4ab326# nacos客户但配置所在分组组名group: DEFAULT_GROUPusername: nacospassword: nacosservice:vgroup-mapping:xgwms_inventory_tx_group: default
以上只是关于seata分布式事务的配置,其它配置省略。启动配置好seata的微服务,控制台结果如下:

在要使用分布式事务的入口方法上添加注解@GlobalTransaction即可实现分布式事务的控制。比如:

场景描述:我把seata部署到了自己购买的一台阿里云服务器上(例如IP为120.26.0.43),使用命令seata-server.bat启动之后,登录到nacos查看,发现seata的ip和阿里云服务器实际ip不同,是一个内网地址,此时又启动了seata客户端,控制台报错,该怎办?

客户端报错:

可是我的服务器地址明明是120.26.0.43,为什么启动之后变成了172.25.60.251?
解决办法:启动seata-server的时候带上参数:seata-server.bat -h 120.26.0.43

此时,seata客户端就可以正常启动了。
我们在停止一个seat客户端后,发现seat-server后台报错,且乱码:

出现了异常:
这个错误是由非正常Seata客户端建立连接引起(如通过http访问Seata server的端口,云服务器的端口扫描等)。这种连接没有发送注册信息,被认为是无用连接,该异常可以忽视。
乱码解决:
打开cmd窗口,输入:chcp 65001意思是设置当前窗口使用UTF-8编码。在该窗口启动seata-server服务,就不会出现乱码了。注意:该方法只能临时设置cmd窗口编码方式,若另开一个cmd窗口,则编码依然是GBK。
