什么是Seata分布式事务解决方案

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

AT模式

AT模式目前来看是Seata框架独有的一种模式,其它的分布式框架上并没有此种模式的实现。其是由二阶段提交演变来的,解决了二阶段提交的同步阻塞等问题。

演变后的两阶段提交协议:

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

Seata框架中有三个概念要阐述下。

  • TC:事务协调器,它是独立的组件,需要独立部署运行,Seata提供了这个独立运行的程序,它负责维护全局事务的运行状态,接收TM指令发起全局事务的提交与回滚,负责与RM通信,协调各个分支事务的提交或回滚。
  • TM:事务管理器,TM需要嵌入应用程序,它负责开启一个全局事务,并定义全局事务的范围,它的目的是最终向TC发起全局提交或回滚指令。
  • RM:与TC通信,控制分支事务,负责分支注册、报告分支事务状态,并接收事务协调器TC的指令,命令分支事务完成本地事务的提交或回滚。

流程示意图如下:

这个图还是比较清晰地,建议是先好好的理解下全流程。

Seata AT模式的具体流程如下。

(1)订单服务收到请求,订单服务中的TM向TC申请开启一个全局事务。(2)TC收到请求,创建一个全局事务,并将全局事务ID(称为XID)返回给订单服务的TM。

(3)订单服务的RM向TC注册分支事务。

(4)订单服务执行本地分支事务的业务逻辑并提交,释放锁定的数据库资源。

(5)订单服务向TC上报本地分支事务的提交结果。

(6)订单服务调用远程的积分服务,此时将XID通过参数传给积分服务。(7)积分服务向TC注册分支事务。

(8)积分服务执行本地分支事务的业务逻辑并提交,释放锁定的数据库资源,并返回订单服务。

(9)积分服务向TC上报本地分支事务的提交结果。

(10)订单服务的TM向TC发起全局事务的提交或回滚。

(11)TC向XID管辖下的全部分支事务发出提交或回滚的指令。

实现原理

我个人觉得框架其实也是一种需求的兑现,只是不像平常开发时那样有产品经理给你输出需求文档(应该也会有,但是少),业务流程不是传统的那种XXX业务,框架的需求一般是偏向技术一些,我把它认为是技术需求;而日常我们做的开发一般是业务需求的兑现。

上面的流程可以看作是需求,那么现在需求出来了,程序猿要怎么实现?

设计思路

TM的设计

流程的开始与结束是由TM决定的,这个TM就是订单服务Controller入口进去后的某个Service方法(当然也可能不是,看你的代码架构,我这里只按照我自己的平常的开发模式来。)在这个Service方法中,处理了订单服务以及积分服务的业务。当Service方法完成后,那么就是整个业务做完了,事务即完成。因此,要我来实现,这个TM对应的Service方法,我会选择用一个注解包裹,通过动态代理的方式,在这个方法的前后分别负责全局事务的开始与结束流程。

RM的设计

RM负责执行具体的业务,将数据入库同时上报给TC。由于二阶段回滚时需要根据回滚日志replay,那么就一定需要记录业务数据执行的日志。那怎么记录?回想了下Mybatis中的数据源代理,这里也是一样的思路。必须拦截或是代理原先的数据源,解析原执行的sql,注入Seata的逻辑,增强其执行逻辑。我们看下RM要做的事情,第一阶段:

第二阶段提交:

第二阶段回滚:

在执行sql的过程中,各个代理对象起到的作用如下

所以在RM端最关键的就是数据源代理以及远程通信。这两块尤其是前者,就是AT模式的技术实现。

TC的设计

TC端需要管理Seata全局事务会话信息,一般是由全局事务、分支事务、全局锁构成,对应表globaltable、branchtable、lock_table。因此在安装部署的时候(file模式除外)都会创建这三个表。从上面来看,目前我们还没有实现隔离性,所谓的隔离性是指多个用户并发访问数据库时,数据库为每个用户开启的事务不能被其他事务的操作所干扰,多个并发事务之间要相互隔离。这也是这里有一个全局锁表的原因。每次本地事务提交前,都会向TC端申请注册分支,同时还会申请全局锁,RM端通过拿到的全局锁保证了读写的隔离性,因此一旦当前事务持有全局锁,那么其他的事务不能提交。

写隔离

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

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

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

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

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

读隔离

seata at 模式默认的隔离级别为读未提交(因为已经提交的sql有可能会回滚)。如果要实现读已提交,select语句需要更改为 SELECT FOR UPDATE 语句。

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

总结

Seata AT可以给你带来一种“无侵入”式的编程体验,你不需要改动任何业务代码,只需要一个注解和少量的配置信息,就可以实现分布式事务。

总结来看,AT模式主要是是基于 DataSource 代理实现的,通过代理 DataSource、Connection、PreparedStatement,拦截 SQL 执行,增强其执行逻辑,由代理侧加入额外的能力以提供分布式事务服务类似自动挡驾驶模式,分布式事务这个强大且复杂的服务能力由Seata框架托管,对业务实现无侵入式,用户仍然只专注于业务 SQL。

聊聊Seata分布式解决方案AT模式的实现原理的更多相关文章

  1. Dubbo学习系列之十四(Seata分布式事务方案AT模式)

    一直说写有关最新技术的文章,但前面似乎都有点偏了,只能说算主流技术,今天这个主题,我觉得应该名副其实.分布式微服务的深水区并不是单个微服务的设计,而是服务间的数据一致性问题!解决了这个问题,才算是把分 ...

  2. 微服务痛点-基于Dubbo + Seata的分布式事务(AT)模式

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

  3. 微服务痛点-基于Dubbo + Seata的分布式事务(TCC模式)

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

  4. 【深入浅出Seata原理及实战】「入门基础专题」探索Seata服务的AT模式下的分布式开发实战指南(2)

    承接上文 上一篇文章说到了Seata 为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案.那么接下来我们将要针对于AT模式下进行分布式事务开发的原理进行介绍以及 ...

  5. Dubbo学习系列之十五(Seata分布式事务方案TCC模式)

    上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...

  6. SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表

    读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...

  7. 5-4 Seata 分布式事务管理

    下载Seata https://github.com/seata/seata/releases https://github.com/seata/seata/releases/download/v1. ...

  8. SpringCloud Alibaba(六) - Seata 分布式事务锁

    1.Seata 简介 1.1 Seata是什么 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事 ...

  9. 【深入浅出Seata原理及实战】「入门基础专题」带你透析认识Seata分布式事务服务的原理和流程(1)

    分布式事务的背景 随着业务的不断发展,单体架构已经无法满足我们的需求,分布式微服务架构逐渐成为大型互联网平台的首选,但所有使用分布式微服务架构的应用都必须面临一个十分棘手的问题,那就是"分布 ...

  10. Seata分布式事务

    使用Seata版本:1.6.1(2023/2/6最新版)该版本存在很多坑,相较于1.0版本,配置上存在很多差别,如果你的版本不同,请不要参考本文. 1.6.1配置存在许多问题,比较难找,如果你使用1. ...

随机推荐

  1. Android笔记--发送彩信

    发送彩信 界面还是那个界面,图片也实现了从相册进行选择图片,选择完成之后,就会回到界面里面的功能: 下面接着实现发送彩信的完整版: 具体实现如下: 界面代码不再展示,主要着重于后台的代码编写啦! 1. ...

  2. 使用Nginx实现本地目录映射

    如果文件是存储在服务器的某个位置,想提供pdf.jpg.png.mp4这些文件的预览功能,可以使用Nginx做虚拟映射,防止他人知道该文件的绝对路径. 如果想预览office文件,先将office文件 ...

  3. 一文带你吃透Redis

    目录 1. 基本数据结构 2. 数据持久化 3. 高可用 4. 缓存 文章字数大约1.9万字,阅读大概需要66分钟,建议收藏后慢慢阅读!!! 1. 基本数据结构 什么是Redis Redis是一个数据 ...

  4. singleflight 使用记录以及源码阅读

    singleflight 使用方法以及源码阅读 1.简介 安装方式: go get -u golang.org/x/sync/singleflight singleflight 是Go官方扩展同步包的 ...

  5. 什么是UV贴图和展开?

    转载:https://baijiahao.baidu.com/s?id=1673723122020029798&wfr=spider&for=pc UV贴图是用于轻松包装纹理的3D模型 ...

  6. markdown---->Typora搭配uPic

    记录一下在mac上面使用Typora和uPic来发表博客的过程,图床用的是阿里Oss.We all, whether we know it or not, are fighting to make t ...

  7. 源码安装slurm

    一.源码安装munge 1.下载munge 下载地址:https://github.com/dun/munge/releases 2.安装编译 tar -Jxvf munge-0.5.15.tar.x ...

  8. 【云享专刊】开源遇上华为云,OCP架构变身“云原生框架”

    摘要:华为云DTSE团队出品云原生改造指南,助力轻松实践OCP上云. 本文分享自华为云社区<[云享专刊]开源遇上华为云,OCP架构变身"云原生框架">,作者:华为云社区 ...

  9. C# System.lnvalidOperationException:"A second operation started on this context before a previousoperation completed. This is usually caused by different threads using the same instance ofDbContext...

    与上一篇问题一样,只是错误不一样,DbContext 不支持并发请求,每个数据库操作都使用await就可以了

  10. STM32新建模板【HAL库】

    看到这篇笔记的小伙伴可能会觉得我在做无用功,明明可以通过 STM32CubeMx 软件直接生成的,还在这里慢慢的创建项目.我觉得在学习的时候最好少借助工具,当我们过度依赖工具的时候,决绝问题的能力可能 ...