深入浅出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, 是阿里中间件,开源的分布式事务解决方案. 前身是阿里的 ...
随机推荐
- 《Java基础——构造器(构造方法)》
Java基础--构造器(构造方法) 总结: 1.构造器名应与类名相同,且无返回值. 2."new 方法"的本质就是在调用构造器. 3.构造器的作用--初始化对象的值. ...
- day40-网络编程02
Java网络编程02 4.TCP网络通信编程 基本介绍 基于客户端--服务端的网络通信 底层使用的是TCP/IP协议 应用场景举例:客户端发送数据,服务端接收并显示控制台 基于Scoket的TCP编程 ...
- Java SE 多态
1.多态 方法的多态 //方法重载体现多态 A a = new A(); //这里我们传入不同的参数,就会调用不同sum方法 System.out.println(a.sum(10,20)); Sys ...
- 重要参考步骤---ProxySQL实现读写分离
MySQL配置主从同步文章地址:https://www.cnblogs.com/sanduzxcvbnm/p/16295369.html ProxySQL实现读写分离与读负载均衡参考文档:https: ...
- 13. 第十二篇 二进制安装kubelet
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247483842&idx=1&sn=1ef1cb06 ...
- 官方使用logstash同步Mysql数据表到ES的摘抄
官方文档地址:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-jdbc.html#plugins-inputs-jdbc ...
- img和div之间有间隙的原因及解决方法
div 中 存在 img标签,由于img标签的 display:inline-block 属性. #####display:inline-block布局的元素在chrome下会出现几像素的间隙,原因是 ...
- 我操作MySQL的惊险一幕
背景 前几天因工作需要,组长给我安排了一个数据清洗的任务. 任务:把 A 表的数据洗到 B 表. 我的第一反应,什么是「洗」?洗数据是什么?洗钱我倒是知道. 不过我不能慌啊,于是问了问组长. 我:组长 ...
- JSP实现登录功能(页面带样式)
功能要求 1.完成两个页面 2.第一个登陆页面login. jsp 3.第二个用户管理页面useManage. jsp 4.有登录功能(能进行用户名密码的校验,用户名若为自己的学号密码为班级号,允许登 ...
- 图片 css剪切,等比例缩放
object-fit: cover; .img1 {//自定义图片宽高,并且等比例缩放 width: 200px; height: 400px; object-fit: cover; }