深入浅出Seata的AT模式

news/2024/11/15 6:54:07/

单个掉队,导致集体被动摆烂;

一、业务背景

在分布式架构中,事务管理是个无法避开的复杂问题,虽然有多种解决方案,但是需要根据业务去选择合适的;

从个人最近几年的实践经验来看,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理论相对平衡的解决方案,并且没有侵入业务工程;



http://www.ppmy.cn/news/1019.html

相关文章

基于C#的公交充值管理系统的设计与实现

项目描述 临近学期结束,还是毕业设计,你还在做C#程序网络编程,期末作业,老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。这里根据疫情当下,你想解决的问题…

vue 相关面试题

vue 相关 v-model 作用 v-model是语法糖,在表单元素上创建双向数据绑定。 1. 监听用户输入和更新数据。 2. 忽略表单元素的value、checked、selected特性的初始值而采用v-model的初始数据。 3. v-model在不同的元素上使用不同的属性并抛出不同的事件。 text和text…

如何基于YAML设计接口自动化测试框架?看完秒会

在设计自动化测试框架的时候,我们会经常将测试数据保存在外部的文件(如Excel、YAML、CSV)或者数据库中,实现脚本与数据解耦,方便后期维护。目前非常多的自动化测试框架采用通过Excel或者YAML文件直接编写测试用例&…

太简单了,一文彻底搞懂Jenkins的用法

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 你想要的,这里都有! 我在前公司的某个部门做过一年CV算法工程师,部门推崇全栈式开发。换句话说,做算法,不能只聚焦于算法,要全流…

【网络杂烩 ---> 网络安全】DLL 注入 --- c/c++ 代码实现(超 · 详细)

麻了,之前写的博客全是收藏,没人点赞,来点赞行不行! GitHub同步更新(已分类):Data_Structure_And_Algorithm-Review 公众号:URLeisure 的复习仓库 公众号二维码见文末 以下是本篇…

【加油站会员管理小程序】02创建数据源

我们上一篇介绍了加油站会员管理小程序的原型,本篇我们推导一下需要的数据源。 推导数据源的办法是要从页面上提炼需要存放的数据,在提炼的过程中要考虑表和表的拆分,主要是考虑主子关系。 在数据源设计中有关联关系和主子表的区分,关联关系是一种组成关系,比如学生和班…

广告和电商应该怎么串联起来呢?我们可以从各大巨头的动作中发掘

电商广告是广告产业与电子商务模式联姻的时代产物,是把广告、传媒、营销推广产业链的各种产品和服务搬到网上,利用网络便捷的实现广告资源信息流通、在线交易和客户关系管理的一种商业模式,是广告业营销模式和渠道的创新。 电商平台从无到有…

[附源码]Python计算机毕业设计SSM酒店管理系统(程序+LW)

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…