开发者学堂课程【全面讲解Spring Cloud Alibaba技术栈(知识精讲+项目实战)第五阶段:Seata介绍】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/687/detail/11927
Seata介绍
内容介绍
一、发展历史
二、设计
三、组成部分
四、执行流程
五、Seata 实现两阶段与传统两阶段的区别
一、发展历史
1、发起时间
首先了解一下 Seata 的发展历史。2019年1月,阿里巴巴中间件团队发起了开源项目称作
Fescar(Fast&EaSyCommitAndRollback),翻译后就是“快速而且容易地进行提交和回滚”。这是和事务相关的项目。
2、发起的愿景
其愿景是让分布式事务的使用像本地事务的使用一样,简单和高效,并逐步解决开发者们遇到的分布式事务方面的所有难题。
3、更名时间
2019年5月,Fescar 更名为Seata,意为 SimpleExtensibleAutonomousTransactionArchitecture,翻译后就是“简单的可拓展的自动事务体系”。这是一套分布式事务解决方案。这个方案就作为阿里巴巴技术站中关于分布式事务的一个解决方案。
二、设计
1、设计目标
Seata 的设计目标是对业务无侵入性,因此从业务无侵入的两阶段提交方案着手进行改造的。
2、设计思路
在介绍分布式事务解决方案时,其中有一个全局事务。全局事务还有另外一个名字为两阶段提交。
它就是在传统两阶段思想的基础上演进。它把一个分布式事务理解成一个包含若干分支事务的全局事务。曾经有一个下单的操作,这个下单就是一个分布式事务。
Seata 把下单的事务理解成订单微服务写入订单这样一个分支事务和商品微服务扣减库存这样一个分支事务的综合体。全局事务的职责是协调其下管往的分支事务达成一致,管理着分支事务,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务。这就是 Seata 的一个大体的设计思路。
三、组成部分
Seata 主要由三个重要组件组成
1、TC:TransactionCoordinator 事务协调器管理全局的分支事务的状态,用于全局性事务的提交和回滚。
2、TM:TransactionManager事务管理器
此前也有一个事务管理器,两者是不一样的。这是 Seata 中的 TM,它是用于开启全局、提交或者回滚全局事务。全局事务的提交和回滚均是由 TM 生效的。
3、RM:ResourceManager 资源管理器
这与之前所学的 RM 很是相似,只是作用更加多一些。资源管理器用于分支事务上的资源管理,并且向 TC 注册分支事务,上报分支事务的状态,接收TC的命令来提交或者回滚分支事务。
4、图文分析
(1)颜色对应11
首先分析一下图中的各项元素。蓝色的部分代表三个应用,也是三个微服务。微服务中间的绿线代表的是远程调用。现在是A服务调用B服务,B服务调用C服务。棕色的代表的是数据库。每一个微服务均有两个数据库与之相对应。黄色的部分均是 Seata 中的定义。
(2)TC、TM、RM 三者的角色
TC为全局事务协调者,TM为全局事务的提交、回滚和发起者。RM为本地资源管理器。每一个微服务中均有本地资源管理器,因为每一个微服务向数据库提交信息需要 RM 的操作。
但是 TM 只出现在了调用链开始的微服务上,因为全局性事务的发起只需要在开始发起可以。下订单这样一个全局事务的发起只需要在订单的微服务上发起,不需要在第二个微服务上再次发起。所以 TM 仅有一个。
四、执行流程
1、A服务的 TM 向 TC 申请开启一个全局事务,TC 就会创建一个全局事务并返回一个唯一的 XID。
2、A服务的 RM 向 TC 注册分支事务,并将其纳入 XID 对应全局事务的管辖。
3、A服务执行分支事务,向数据库做操作。
4、A服务开始远程调用B服务,此时XID会在微服务的调用链上传播。
5、B服务的RM向TC注册分支事务,并将其纳入XID对应的全局事务的管理。
6、B服务执行分支事务,向数据库做操作。
7、全局事务调用链处理完毕,TM 根据有无异堂向 TC 发起全局事务的提交或者回滚。
8、TC 协调其管辖之下的所有分支事务,决定是否回滚。
案例分析:
比如有一个下订单的请求,由 TM 在 TC 中注册一个全局事务。开启以后,会由TC会反馈一个全局事务的ID账号,即 XID。XID 其实就是三个微服务所在全局事务的唯一标识。接下来由 RM 再次向TC注册一个分支事务。注册的分支事务是在 XID 全局事务的管辖之下的。比如一条直线即是一个全局事务,分支事务就是直线上分布的叉。这个全局事务可以把各个分支事务串联起来。这时 TC 也会给分支事务返回一个分支事务的标识。A服务就会执行本地的分支事务并进行提交,提交完成后就会调用微服务B。微服务B也会向 TC 注册一个B服务上的分支事务。
一直在调用C服务完毕之后就相当于有三个分支事务被 XID 这个全局事务串联在一起。三个分支事务全部执行完毕以后TM就会检测这三个分支事务是否全部执行成功。如果全部执行成功,就会向 TC发起一个全局的提交请求。如果其中有失败的,就会向 TC 发起一个全局回滚的请求。
接着 TC 又会借用本地事务的资源管理器 RM,进行全局事务的提交回滚。全局事务提交的回滚其实就是各个分支里面进行各自事务的提交回滚。
五、Seata实现两阶段与传统两阶段的差别
1.架构层次方面
传统两阶段方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过XA协议实现,而 Seata 的 RM 是以 jar 包的形式作为中间件层部署在应用程序这一侧的。传统两阶段提交的 RM 其实指的就是数据库。而 Seata 中的RM不仅仅是数据库,其中其实是存在一些代码的。这个 Jar 包除了管理数据库还有其他的功能,比如注册分支事务、提交或回滚本地的分支事务,均是由 RM 来完成的。
2.两阶段提交方面
传统的两阶段无论第二阶段的决议是 commit 还是 rollback,事务性资源的锁都要保持到第二阶段完成后才可以释放。而Seata的做法是在第一阶段就将本地事务提交,这样就可以省去保持到第二阶段资源锁的时间,整体提高效率。
微服务A调用微服务B,在微服务A的本地事务执行完成之后,数据库中已经被提交了,而后去调用微服务B。这其实会把提交之前的和提交之后的全部写到一个日志中。
如果微服务C出现问题,TC 就会调用程序反向读日志,再把数据进行修改,就是这样一个回滚的过程。