聊聊Seata分布式解决方案AT模式的实现原理
什么是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。
- tx1 先开始,开启本地事务,拿到本地锁,更新操作 m = 1000 - 100 = 900。本地事务提交前,先拿到该记录的全局锁 ,本地提交释放本地锁。
- tx2 后开始,开启本地事务,拿到本地锁,更新操作 m = 900 - 100 = 800。本地事务提交前,尝试拿该记录的全局锁,tx1 全局提交前,该记录的全局锁被 tx1 持有,tx2 需要重试等待全局锁。
- 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模式的实现原理的更多相关文章
- Dubbo学习系列之十四(Seata分布式事务方案AT模式)
一直说写有关最新技术的文章,但前面似乎都有点偏了,只能说算主流技术,今天这个主题,我觉得应该名副其实.分布式微服务的深水区并不是单个微服务的设计,而是服务间的数据一致性问题!解决了这个问题,才算是把分 ...
- 微服务痛点-基于Dubbo + Seata的分布式事务(AT)模式
前言 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. ...
- 微服务痛点-基于Dubbo + Seata的分布式事务(TCC模式)
前言 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案. ...
- 【深入浅出Seata原理及实战】「入门基础专题」探索Seata服务的AT模式下的分布式开发实战指南(2)
承接上文 上一篇文章说到了Seata 为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案.那么接下来我们将要针对于AT模式下进行分布式事务开发的原理进行介绍以及 ...
- Dubbo学习系列之十五(Seata分布式事务方案TCC模式)
上篇的续集. 工具: Idea201902/JDK11/Gradle5.6.2/Mysql8.0.11/Lombok0.27/Postman7.5.0/SpringBoot2.1.9/Nacos1.1 ...
- SpringCloud微服务实战——搭建企业级开发框架(二十七):集成多数据源+Seata分布式事务+读写分离+分库分表
读写分离:为了确保数据库产品的稳定性,很多数据库拥有双机热备功能.也就是,第一台数据库服务器,是对外提供增删改业务的生产服务器:第二台数据库服务器,主要进行读的操作. 目前有多种方式实现读写分离,一种 ...
- 5-4 Seata 分布式事务管理
下载Seata https://github.com/seata/seata/releases https://github.com/seata/seata/releases/download/v1. ...
- SpringCloud Alibaba(六) - Seata 分布式事务锁
1.Seata 简介 1.1 Seata是什么 Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata 将为用户提供了 AT.TCC.SAGA 和 XA 事 ...
- 【深入浅出Seata原理及实战】「入门基础专题」带你透析认识Seata分布式事务服务的原理和流程(1)
分布式事务的背景 随着业务的不断发展,单体架构已经无法满足我们的需求,分布式微服务架构逐渐成为大型互联网平台的首选,但所有使用分布式微服务架构的应用都必须面临一个十分棘手的问题,那就是"分布 ...
- Seata分布式事务
使用Seata版本:1.6.1(2023/2/6最新版)该版本存在很多坑,相较于1.0版本,配置上存在很多差别,如果你的版本不同,请不要参考本文. 1.6.1配置存在许多问题,比较难找,如果你使用1. ...
随机推荐
- python轮流监听多台服务器资源情况
在主动持续监听某台服务器基础上,优化为同时监听多台服务器资源占用情况: 优点:较初版,设备监听范围有了明显提升: 缺点:主动式,轮询方式,实时性较差. #-*- coding: utf-8 -*- # ...
- Java 2023年接地气的中高级面试题一(附答案)
直入主题: Q1:为什么要用分布式锁? 在分布式系统中,多个进程或线程可能会同时访问共享资源,这可能会导致数据不一致.并发性问题.性能下降等问题.为了解决这些问题,我们通常会使用分布式锁来协调多个进程 ...
- 在线调试工具 Arthas
Arthas(阿尔萨斯) 是 Alibaba开源的一款 Java在线诊断工具,能够分析,诊断,定位Java应用问题,例如:JVM信息,线程信息,搜索类中的方法,跟踪代码执行,观测方法的入参和返回参数等 ...
- python入门教程之三编码问题
1编码问题 Python文件中如果未指定编码,在执行过程中会出现报错: !/usr/bin/python print ("你好,世界") 以上程序执行输出结果为: 文件" ...
- [Linux]浅析"command > /dev/null 2>&1 &" 与 "command 1>/dev/null 2>&1 &"
1 问题描述 1.1 问题描述 在一项目中查看CENTOS 服务器的定时任务crontab时查看到如下这段命令: 命令clearLog.sh > /dev/null 2>&1 &a ...
- [Linux]常用命令之【source|export/env】#点命令/环境变量#
1 source 1-1 source 命令概述 source命令用法:source FileName 简述 source命令(从 C Shell 而来)是bash shell的内置命令. sourc ...
- vulnhub靶场之DRIFTINGBLUES: 5
准备: 攻击机:虚拟机kali.本机win10. 靶机:DriftingBlues: 5,下载地址:https://download.vulnhub.com/driftingblues/driftin ...
- xtrabackup: error: xb_load_tablespaces() failed with error code 57
问题描述:在数据库上运行xtrabackup备份脚本出现的一些报错 DB_version:mysql8.0.26 Xtrabackup:percona-xtrabackup-8.0.27-19-Lin ...
- AI时代下普通小程序员的想法
在我接触了一系列AI技术后,不禁产生了许多思考.我先后尝试了AI编程.AI写论文.AI写小说.AI绘画等,最近看到了一些关于AI构建虚拟世界以及Auto-GPT的AI类新闻.在这个过程中,我心头涌现出 ...
- Hugging News #0414: Attention 在多模态情景中的应用、Unity API 以及 Gradio 主题构建器
每一周,我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新,包括我们的产品和平台更新.社区活动.学习资源和内容更新.开源库和模型更新等,我们将其称之为「Hugging Ne ...