22. 分布式事务框架Seata
1. 分布式事务
1.1 我们先回顾下事务
事务
是指数据库中的一组操作,这些操作要么全部成功执行,要么全部回滚,以保持数据的一致性和完整性。事务具有以下四个特性,通常称为ACID特性:
- 原子性(Atomicity):事务中的所有操作要么全部执行成功,要么全部失败回滚,没有中间状态。
- 一致性(Consistency):事务的执行使数据库从一个一致性状态转移到另一个一致性状态。事务在开始和结束时,数据库必须满足预定义的一致性规则。
- 隔离性(Isolation):事务的执行应该与其他并发执行的事务相互隔离,每个事务都感觉不到其他事务的存在。
- 持久性(Durability):一旦事务提交,其对数据库的修改应该是永久性的,即使在系统故障的情况下也不应丢失。
本地事务
:Spring本地事务使用@Transactional 大多数场景下,我们的应用都只需要操作单一的数据库,这种情况下的事务被称之为本地事务(Local Transaction)。本地事务的ACID特性是数据库直接提供支持。
分布式事务
(Distributed Transaction)是指跨越多个分布式系统的事务,其中涉及到多个独立的参与者和资源。分布式事务需要确保多个参与者之间的操作的一致性和原子性。
1.2 分布式事务问题
如图,用户购买商品的业务逻辑。整个业务逻辑由3个微服务提供支持:
- 仓储服务(Stock):对给定的商品扣除仓储数量。
- 订单服务(Order):根据采购需求创建订单。
- 账户服务(Account):从用户账户中扣除余额。
单体应用被拆分成微服务应用,原来的三个模块被拆分为三个独立的应用,分别使用三个独立的数据源。 业务操作需要调用三个服务来完成,此时每个服务内部的数据一致性由本地事务来保证,但是全局的数据一致性问题没法保证。 故一次业务操作需要跨多个数据源或者需要跨多个系统进行远程调用,就会产生分布式事务问题
。
由于网络延迟、节点故障、通信失败等原因,导致分布式事务无法像单个系统的事务那样简单地实现ACID特性。
常见的分布式事务问题包括
:
- 部分失败:在一个分布式事务中,有些参与者执行成功,而其他参与者执行失败,导致事务的部分操作成功,部分操作失败。
- 数据不一致:在一个分布式事务中,数据的一致性无法保证,可能因为参与者之间的数据冲突或者数据同步延迟。
1.3 一般事务的解决方案为什么不能作用于分布式事务?
解决一般事务问题的方法,例如使用数据库的ACID特性、锁机制、回滚和恢复机制等,无法直接应用于分布式事务问题,原因如下:
- 并发控制问题:在分布式环境中,由于多个事务同时执行,并发控制变得更加复杂。传统的锁机制在分布式环境中无法有效地协调多个参与者之间的并发访问。
- 通信故障:分布式事务中的参与者之间通过网络进行通信,网络延迟、断开连接或消息丢失可能导致事务协调失败或超时。
- 参与者故障:在分布式系统中,参与者可能由于硬件故障、软件错误或其他原因而崩溃或无响应。这可能导致事务无法完成或导致数据不一致。
- 同步问题:在分布式环境中,数据的复制和同步可能存在延迟,导致不同参与者之间的数据不一致。
- 跨越多个系统:分布式事务涉及跨越多个独立的系统,每个系统可能具有不同的事务管理机制和数据存储方式,这增加了事务管理的复杂性。
2. 分布式事务解决方案
这里先简单提及一下常见的分布式事务解决方案
:
- seata阿里分布式事务框架
- 消息队列
- saga
- XA
这四种常见的分布式事务解决方案,分别对应着分布式事务的四种模式
:AT、TCC、Saga、XA;
四种分布式事务模式,都有各自的理论基础,分别在不同的时间被提出;每种模式都有他的适用场景,同样每个模式也都诞生有各自的代表产品,而这些代表产品,可能就是我们常见的(全局事务、基于可靠消息、最大努力通知、TCC)
。
分布式事务相关的协议有2PC、3PC。由于三阶段提交协议3PC非常难实现,目前市面主流的分布式事务解决方案都是2PC协议。两阶段提交协议
顾名思义,分为两个阶段:Prepare和Commit。
TCC(Try-Confirm-Cancel)实际上是服务化的两阶段提交协议。
3. 分布式事务框架Seata
3.1 Seata是什么
【Seata官网】
Seata(Simple Extensible Autonomous Transaction Architecture)是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT
、TCC
、SAGA
和 XA四种事务模式
,为用户打造一站式的分布式解决方案,包括事务管理、本地事务协调、分布式事务日志和分布式锁等组件。
Seata通过使用分布式事务日志和分布式锁来保证事务的一致性和可靠性。分布式事务日志记录全局事务的操作日志,并提供了事务的恢复和回滚能力。分布式锁用于保护全局事务在不同参与者之间的并发访问,确保数据的一致性和正确性。
3.2 Seata整体架构
一个典型的分布式事务过程分为一ID(全局事务id)+三组件
模型。
- TC (Transaction Coordinator) - 事务协调者 维护全局和分支事务的状态,驱动全局事务提交或回滚。
- TM (Transaction Manager) - 事务管理器 定义全局事务的范围:开始全局事务、提交或回滚全局事务。
- RM (Resource Manager) - 资源管理器 管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
Seata的整体架构如上图,分TC、TM和RM三个角色,TC(Server端)为单独服务端部署,负责维护分布式事务的运行状态,TM和RM(Client端)由业务系统集成,TM是一个分布式事务的发起者和终结者,而RM则负责本地事务的运行并上报。
一个典型的事务过程
:
1、TM向TC申请开启一个全局事务 ,全局事务创建成功并生成一个全局唯一的XID;
2、XID在微服务调用链路的上下文中传播;
3、RM向TC注册分支事务,将其纳入XID对应全局事务的管辖;
4、TM向TC发起针对XID的全局提交或回滚决议;
5、TC调度XID下管辖的全部分支事务完成提交或回滚请求;
3.3 Seata支持的配置中心
Seata是一个分布式事务,seata服务端也是一个微服务,需要和其他微服务一样需要注册中心和配置中心
。
Seata支持的配置中心 | Seata支持的注册中心 |
---|---|
nacos consul apollo etcd zookeeper file (读本地文件, 包含conf、properties、yml配置文件的支持) | eureka consul nacos etcd zookeeper sofa redis file (直连) |
3.4 事务信息存储配置
Server 端存储模式(store.mode)支持三种方式:
存储模式 | 初始化 | 说明 |
---|---|---|
file 单机模式(默认为此模式) | 无需改动,直接启动 | 全局事务会话信息存储在内存中,读写并持久化至本地文件 root.data (bin\sessionStore\root.data) 中,性能较高 |
db 高可用模式(Mysql 5.7+) | 1. 初始DB:seata/script/server/db/mysql.sql 2. 修改存储模式:store.mode=“db” 3. 修改存储数据源:store.db相关属性 | 全局事务会话信息通过db共享,相应性能差些 |
redis (Seata-Server 1.3及以上版本支持) | 1. 修改存储模式:store.mode=“redis” 2. 修改存储数据源:store.redis相关属性 | 性能较高,存在事务信息丢失风险,需提前配置合适当前场景的redis持久化配置 |
3.5 微服务集成seata
Seata安装与环境搭建参看:Seata1.5.2+Nacos分布式事务环境搭建