分布式事务解决方案——Alibaba-seata

一、seata介绍

官方文档:Seata 是什么

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

Seata术语

TC (Transaction Coordinator) - 事务协调者

维护全局和分支事务的状态,驱动全局事务提交或回滚。

负责通知命令的中间件Seata-Server

TM (Transaction Manager) - 事务管理器

定义全局事务的范围:开始全局事务、提交或回滚全局事务。

决定什么时候全局提交、回滚

RM (Resource Manager) - 资源管理器

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

真正操作每一个数据库的数据

分布式事务解决方案——Alibaba-seata_第1张图片

Seata提供了四种不同的分布式事务解决方案

  • XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入
  • AT模式:最终一致的分阶段事务模式,无业务侵入(默认模式)
  • TCC模式:最终一致的分阶段事务模式,有业务侵入
  • SAGA模式:长事务模式,有业务入侵

分布式事务解决方案——Alibaba-seata_第2张图片

二、二阶段提交通用设计概念

将需要两个阶段完成分布式事务处理的操作,称为二阶段提交

(不同厂商所提出的解决方案不同)

1、业务场景

分布式事务解决方案——Alibaba-seata_第3张图片

 2、操作流程

分布式事务二阶段提交处理过程 (操作请求由事务协调着发出)

  1. 事务协调者向各个服务发起数据操作的请求,开启全局事务
  2. 每一个服务,sql操作完,都不进行提交(未提交状态)
  3. 当所有模块,都向事务协调者通知,自己已经执行完成
  4. 事务协调者额外的再次向各模块发出通知,可以执行事务提交

分布式事务解决方案——Alibaba-seata_第4张图片

分布式事务解决方案——Alibaba-seata_第5张图片

 

三、XA模式

XA规范是分布式事务处理标准,它描述了全局的TM和局部的RM之间的接口,几乎所有的主流的数据库都对XA规范提供了支持;

执行原理:

XA将分布式事务分为两个阶段,一个是准备阶段,一个是执行阶段。

  • 准备阶段: 事务协调者会向事务参与者RM发送一个请求,这里的RM其实是由数据库实现的,所以可以认为RM就是数据库。让数据库去执行事务,但执行完不要提交,而是把结果告知事务协调者
  • 执行阶段: 事务协调者根据结果,通知RM回滚或者提交事务

分布式事务解决方案——Alibaba-seata_第6张图片

分布式事务解决方案——Alibaba-seata_第7张图片

总结:

XA模式优点:

这是一种强一致性的解决方案,因为每一个微服务都是基于各自的事务的,各自的事务是满足ACID的,而且等到大家都执行完了且都成功了才提交,所以全局事务是满足ACID的。

实现比较简单,因为很多数据库都实现了这种模式,使用Seata的XA模式只需要简单的封装上TM。

XA模式缺点:

第一阶段不提交,等到第二阶段再提交,但是等的过程中要占用数据库锁,如果一个分布式事务中跨越了很多个分支事务,则可能造成很多资源的浪费,使得别的请求无法访问,降低了可用性;

依赖于数据库,对于如果有的数据库没有实现这种模式,则无法使用这个模式来实现分布式事务。
 

实现:

分布式事务解决方案——Alibaba-seata_第8张图片

四、AT模式(默认)

每个RM中有个undo_log表(数据快照),里面会记录一些数据,比如逆向sql,用于还原

执行原理:

  • 一阶段:业务数据和回滚日志记录在同一个本地事务中提交, 提交异步化,非常快速地完成,释放本地锁和连接资源。
  • 二阶段:回滚通过一阶段的回滚日志进行反向补偿

分布式事务解决方案——Alibaba-seata_第9张图片

分布式事务解决方案——Alibaba-seata_第10张图片

 分布式事务解决方案——Alibaba-seata_第11张图片

总结:

AT模式于XA模式的区别:

AT模式 XA模式
第一阶段直接提交,不锁定资源 第一阶段不提交事务,会锁定资源
TC上的全局锁:只是记录操作某张表的某行的全局事务,是由Seata管理的,对于不是Seata管理的相关事务,依旧可以直接操作数据表。比如由其他业务要修改同张表同行数据的其他字段,这个时候是可以的 XA中事务不提交,占用的是数据库的锁,所有的crud的操作都会被限制
利用数据快照实现数据回滚 依赖数据库机制实现回滚
最终一致 强一致

AT模式优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交

AT模式缺点:

  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能影响性能,但比XA模式要好很多

AT模式避免并发场景下的脏读、脏写

(1)写隔离

  • 一阶段本地事务提交前,需要确保先拿到 全局锁 。
  • 拿不到 全局锁 ,不能提交本地事务。
  • 拿 全局锁 的尝试被限制在一定范围内,超出范围将放弃,并回滚本地事务,释放本地锁。

以一个示例来说明:

两个全局事务 tx1 和 tx2,分别对 a 表的 m 字段进行更新操作,m 的初始值 1000。

tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的 全局锁 ,本地提交释放本地锁。 tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的 全局锁 ,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待 全局锁 。

分布式事务解决方案——Alibaba-seata_第12张图片

tx1 二阶段全局提交,释放 全局锁 。tx2 拿到 全局锁 提交本地事务。

分布式事务解决方案——Alibaba-seata_第13张图片

如果 tx1 的二阶段全局回滚,则 tx1 需要重新获取该数据的本地锁,进行反向补偿的更新操作,实现分支的回滚。

此时,如果 tx2 仍在等待该数据的 全局锁,同时持有本地锁,则 tx1 的分支回滚会失败。分支的回滚会一直重试,直到 tx2 的 全局锁 等锁超时,放弃 全局锁 并回滚本地事务释放本地锁,tx1 的分支回滚最终成功。

因为整个过程 全局锁 在 tx1 结束前一直是被 tx1 持有的,所以不会发生 脏写 的问题。

(2)读隔离

在数据库本地事务隔离级别 读已提交(Read Committed) 或以上的基础上,Seata(AT 模式)的默认全局隔离级别是 读未提交(Read Uncommitted) 。

如果应用在特定场景下,必需要求全局的 读已提交 ,目前 Seata 的方式是通过 SELECT FOR UPDATE 语句的代理。

分布式事务解决方案——Alibaba-seata_第14张图片

SELECT FOR UPDATE 语句的执行会申请 全局锁 ,如果 全局锁 被其他事务持有,则释放本地锁(回滚 SELECT FOR UPDATE 语句的本地执行)并重试。这个过程中,查询是被 block 住的,直到 全局锁 拿到,即读取的相关数据是 已提交 的,才返回。

出于总体性能上的考虑,Seata 目前的方案并没有对所有 SELECT 语句都进行代理,仅针对 FOR UPDATE 的 SELECT 语句。

实现:

分布式事务解决方案——Alibaba-seata_第15张图片

 

你可能感兴趣的:(分布式,微服务系列,分布式,java,微服务)