认识Seata
# 认识 Seata
# 分布式事务
首先我们看看项目中的下单业务整体流程:
由于订单、购物车、商品分别在三个不同的微服务,而每个微服务都有自己独立的数据库,因此下单过程中就会跨多个数据库完成业务。而每个微服务都会执行自己的本地事务:
- 交易服务:下单事务
- 购物车服务:清理购物车事务
- 库存服务:扣减库存事务
整个业务中,各个本地事务是有关联的。因此每个微服务的本地事务,也可以称为分支事务。多个有关联的分支事务一起就组成了全局事务。我们必须保证整个全局事务同时成功或失败。
我们知道每一个分支事务就是传统的单体事务,都可以满足ACID特性,但全局事务跨越多个服务、多个数据库,是否还能满足呢?
我们来做一个测试,先进入购物车页面:
- 目前有 4 个购物车,然结算下单,进入订单结算页面,
- 然后将购物车中某个商品的库存修改为
0
, - 然后,提交订单,最终因库存不足导致下单失败,
- 然后去查看购物车列表,发现购物车数据依然被清空了,并未回滚。
事务并未遵循 ACID 的原则,归其原因就是参与事务的多个子业务在不同的微服务,跨越了不同的数据库。虽然每个单独的业务都能在本地遵循ACID,但是它们互相之间没有感知,不知道有人失败了,无法保证最终结果的统一,也就无法遵循ACID的事务特性了。
这就是分布式事务问题,出现以下情况之一就可能产生分布式事务问题:
- 业务跨多个服务实现
- 业务跨多个数据源实现
接下来这一章我们就一起来研究下如何解决分布式事务问题。
# 认识 Seata
# 概念
解决分布式事务的方案有很多,但实现起来都比较复杂,因此我们一般会使用开源的框架来解决分布式事务问题。
在众多的开源分布式事务框架中,功能最完善、使用最多的就是阿里巴巴在 2019 年开源的 Seata 了。
https://seata.io/zh-cn/docs/overview/what-is-seata.html (opens new window)
其实分布式事务产生的一个重要原因:就是参与事务的多个分支事务互相无感知,不知道彼此的执行状态。
因此解决分布式事务的思想非常简单:
就是找一个统一的事务协调者,与多个分支事务通信,检测每个分支事务的执行状态,保证全局事务下的每一个分支事务同时成功或失败即可。大多数的分布式事务框架都是基于这个理论来实现的。
# 三个角色
Seata 也不例外,在 Seata 的事务管理中有三个重要的角色:
- TC **(Transaction Coordinator - 事务协调者:**维护全局和分支事务的状态,协调全局事务提交或回滚。
- TM (Transaction Manager) - **事务管理器:**定义全局事务的范围、开始全局事务、提交或回滚全局事务。
- RM (Resource Manager) - **资源管理器:**管理分支事务,与【TC】交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
# 工作架构图
Seata 的工作架构如图所示:
其中,**TM **和 RM 可以理解为 Seata 的客户端部分,引入到参与事务的微服务依赖中即可。
将来 TM 和 RM 就会协助微服务,实现本地分支事务与 TC 之间交互,实现事务的提交或回滚。
而 TC 服务则是【事务协调中心】,是一个独立的微服务,需要单独部署。
# 官方文档
官网首页:Apache Seata (opens new window)
快速开始 | Spring Cloud Alibaba (spring-cloud-alibaba-group.github.io) (opens new window)
# 四种模式
- AT 模式,默认,简单,需要增加 undo_log 表,生成反向 SQL,性能高
- 回滚后,原来没数据的,现在还是没数据
- TCC 模式,try、confirm/cancel,三个阶段的代码都得自己实现,Seata 只负责调度
- 对业务代码侵入性较强,必要时可能还要修改数据库
- SAGA 模式,长事务解决方案,需要程序员自己编写两阶段代码(AT 模式不需要写第二阶段)
- 基于状态机来实现的,需要一个 JSON 文件,可异步执行
- XA 模式,XA 协议是由 X/Open 组织提出的分布式事务处理规范,基于数据库的 XA 协议来实现 2PC 又称为 XA 方案,适用于强一致性的场景,比如金融、银行等
- 需要数据库本身支持XA协议,可以跨数据库
# AT 模式
seata 的 AT 模式会自动生成反向 sql,且没有反引号
``
,所以要求表里不能有关键字。AT 模式会有个全局锁,用于防止脏读,线程 1 的事务修改了库存,但还没提交事务,线程 2 读库存时,读的还是原来的库存。
# 学习参考
day05-服务保护和分布式事务 - 飞书云文档 (feishu.cn) (opens new window)