深入浅出Seata的AT模式
单个掉队,导致集体被动摆烂;
一、业务背景
在分布式架构中,事务管理是个无法避开的复杂问题,虽然有多种解决方案,但是需要根据业务去选择合适的;
从个人最近几年的实践经验来看,Seata组件的AT模式比较常用,本文从实际的案例出发,来深入分析该模式的原理;
首先创建一个全局事务管理的接口,这里是在Facade服务中开启全局事务;
请求经过三个微服务,并且各个服务都进行数据源的操作,然后模拟链路成功和异常的情况,来分析不同状态的逻辑实现;
二、Seata架构
1、核心组件
三大组件
- TC:事务协调者
即Transaction Coordinator,维护全局和分支事务的状态,驱动全局事务提交或回滚。
- TM:事务管理器
即Transaction Manager,定义全局事务的范围,开始事务、提交事务,回滚事务。
- RM:资源管理器
即Resource Manager,管理分支事务处理的资源,向TC注册分支事务,报告分支事务的状态,驱动分支事务提交或回滚。
基础交互
TC是需要独立部署的服务,TM和RM是集成在服务中,三大组件相互协作,共同完成分布事务的管理;
2、AT模式
事务模型
AT是Seata默认的模式,需要基于支持本地ACID事务的关系型数据库;Java应用,通过JDBC访问数据库;基于案例流程,先分析AT的事务模型;
2.1 TM负责定义全局事务的边界,向TC申请,开启一个全局事务;
2.2 全局事务创建成功后,生成全局唯一的XID;
2.3 XID会在微服务请求链路上下文中传播;
2.4 RM向TC注册分支事务,并归属到XID对应的全局事务进行调度;
2.5 TM向TC发起相应XID的全局事务提交或回滚决议;
2.6 TC完成对XID管理的全部分支事务提交或回滚的调度;
核心机制
执行阶段:每个微服务的请求完成后,基于本地数据库的事务能力,保证业务数据和回滚日志在同一个本地事务中提交,快速释放连接和对资源的锁定;
完成阶段:全局提交时分支事务已经完成提交,会清理回滚日志,快速结束流程;全局回滚基于XID和BranchID查询回滚日志,完成数据回滚;
数据源代理
在AT模式中,应用需要使用Seata组件中的JDBC代理数据源DataSourceProxy,实现对真正目标数据源的代理访问;
三、案例分析
1、流程分析
案例的简单描述
在案例中涉及三个服务,Facade服务开启全局事务,然后分别请求Account和Quartz服务的更新接口,通过Quartz接口是否抛异常来调试AT模式的原理;
从实际的请求执行来说,绝大多数的请求都是可以执行成功的,而AT模式的异步化提交极大限度的顾及全局事务的效率问题,少数失败的情况也可以通过回滚日志进行反向补偿;
2、写隔离
上述流程分析AT模式的原子性,即多个分支事务要么都成功要么都失败,接下来分析多个事务中的全局锁隔离机制,先看写隔离,假设TX1先开始;
TX1逻辑
- TX1开始本地事务,拿到本地锁,然后执行更新操作;
- TX1本地事务提交前,需要先获取全局锁,否则无法提交;
- TX1获取全局锁并提交,释放本地锁,但未释放全局锁;
TX2逻辑
- TX2此时开始本地事务,拿到本地锁;
- TX2执行本地事务提交前,尝试获取全局锁;
- 由于全局锁被TX1持有,TX2会重试等待全局锁;
假设TX1全局提交
- TX1如果全局事务提交,会释放全局锁;
- TX2获取全局锁成功,执行本地事务提交;
假设TX1全局回滚
- TX1如果全局事务回滚,要重新获取数据的本地锁,进行回滚的补偿动作;
- TX2如果仍在等待全局锁,并且还持有本地锁,TX1事务回滚失败,会不断的重试;
- 当TX2等待全局锁超时,会放弃全局锁并回滚本地事务,释放本地锁;
- TX1最终获取数据的本地锁,完成回滚动作;
在该过程中,TX1在结束前一直持有全局锁,TX2获取不到全局锁无法对相同的数据执行更新动作,所以避免了脏写的问题;
3、读隔离
在数据库本地隔离级别为读已提交或以上的基础上,Seata的AT模式默认全局隔离级别是读未提交;如果需要全局的读已提交,可以通过SELECT FOR UPDATE
语句的代理;
该语句的执行也需要获取全局锁,如果全局锁被TX1持有,TX2会释放本地锁,查询会被阻塞并进行重试,拿到全局锁读取成功后返回;
四、对比XA模式
XA是一个分布式事务分段提交协议;事务管理器即TM:作为全局事务的调度者,负责整个事务中本地资源的提交和回滚;本地资源管理器即RM:大部分关系型数据库都实现了XA接口;
TM先向所有的参与事务的RM发送确认请求,根据确认的结果,判断是调用RM的commit提交还是rollback回滚;
XA具有强一致性,在2段提交的过程中,会持有资源的锁,如果是在交易下单等复杂链路中,并且并发量很高,会存在长事务风险,XA无法满足该类高并发的场景;
而在Seata的AT模式中,在服务执行完成后,直接进行RM提交和资源释放,提供了对CAP理论相对平衡的解决方案,并且没有侵入业务工程;
五、参考源码
应用仓库:
https://gitee.com/cicadasmile/butte-flyer-parent
组件封装:
https://gitee.com/cicadasmile/butte-frame-parent
深入浅出Seata的AT模式的更多相关文章
- 分布式事务与Seate框架(3)——Seata的AT模式实现原理
前言 在上两篇博文(分布式事务与Seate框架(1)--分布式事务理论.分布式事务与Seate框架(2)--Seata实践)中已经介绍并实践过Seata AT模式,这里一些例子与概念来自这两篇(特别是 ...
- 阿里神器 Seata 实现 TCC模式 解决分布式事务,真香!
今天这篇文章介绍一下Seata如何实现TCC事务模式,文章目录如下: 什么是TCC模式? TCC(Try Confirm Cancel)方案是一种应用层面侵入业务的两阶段提交.是目前最火的一种柔性事务 ...
- 深入浅出AQS之共享锁模式
在了解了AQS独占锁模式以后,接下来再来看看共享锁的实现原理. 原文地址:http://www.jianshu.com/p/1161d33fc1d0 搞清楚AQS独占锁的实现原理之后,再看共享锁的实现 ...
- 深入浅出设计模式——简单工厂模式(Simple Factory)
介绍简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些.因为它至少不是Gof23种设计模式之一.但它在实际的编程中经常被用到,而且思想也非常简单,可以说是工厂方法模式的一个引导,所以我想 ...
- 深入浅出设计模式——工厂方法模式(Factory Method)
介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...
- 深入浅出设计模式——抽象工厂模式(Abstract Factory)
模式动机在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一个工厂可 ...
- 深入浅出设计模式——享元模式(Flyweight Pattern)
模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.享元模式正是为解决这一类问题而诞生 ...
- 深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)
模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传 ...
- 深入浅出设计模式——中介者模式(Mediator Pattern)
模式动机 在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题: 系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他 ...
- linux(centos8):安装分布式事务服务seata(file单机模式,seata 1.3.0/centos 8.2)
一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件,开源的分布式事务解决方案. 前身是阿里的 ...
随机推荐
- 对循环神经网络参数的理解|LSTM RNN Input_size Batch Sequence
在很多博客和知乎中我看到了许多对于pytorch框架中RNN接口的一些解析,但都较为浅显甚至出现一些不准确的理解,在这里我想阐述下我对于pytorch中RNN接口的参数的理解. 我们经常看到的RNN网 ...
- ubuntu20.04详细安装教程
1.运行虚拟机,加载一段时间后弹出"安装"界面.语言栏倒数第三个是中文.点击[安装 Ubuntu]. 2.键盘布局,[继续] 3.更新和其他软件,取消[安装Ubuntu时下载更新] ...
- 基于QT和C++实现的翻金币游戏
基于QT和C++的翻金币游戏 声明: QT翻金币项目可以说是每个新学QT的同学都会去写的一个项目,网上的源码也很多,我也是最近刚开始学QT,所以也参考了很多前辈的代码自己重新敲了一遍代码. 游戏介绍: ...
- Dubbo 03: 直连式 + 接口工程
进一步改正dubbo框架中简单的直连式的不足 需要用到3个相互独立的maven工程,项目1为maven的java工程作为接口工程,项目2,3为maven的web工程 工程1:o3-link-inter ...
- 齐博X1-栏目的调用2
fun('sort@fathers',$fid,'cms') 获取上层多级栏目这样的,比如我们现在所属第三级栏目,现在可以利用这个函数获取第二级和第一级的栏目,当然自身也会被调用出来,所以此函数用的 ...
- .net core -利用 BsonDocumentProjectionDefinition 和Lookup 进行 join 关联 MongoDB 查询
前序 前段时间由于项目需要用到MongoDB,但是MongoDB不建议Collection join 查询,网上很多例子查询都是基于linq 进行关联查询.但是在stackoverflow找到一个例 ...
- C语言整人关机程序
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char input ...
- 4.pygame快速入门-事件监听
事件event:游戏启动后,用户针对游戏的所有操作 监听:在游戏循环中,判断用户的具体操作 pygame中通过pygame.event.get()可以获得当前用户所做动作的事件列表 事件监听 wh ...
- 闻道Go语言,6月龄必知必会
大家好,我是马甲哥, 学习新知识, 我的策略是模仿-->归纳--->举一反三, 在同程倒腾Go语言一年有余,本次记录<闻道Go语言,6月龄必知必会>,形式是同我的主力语言C#做 ...
- 第二阶段:高级核心基础知识·第4章shell特性·2
1.统计日志,日志内容 39.96.187.239 - - [11/Nov/2019:10:08:01 +0800] "GET / HTTP/1.1" 302 0 "-& ...