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

一、业务背景

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

从个人最近几年的实践经验来看,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模式的更多相关文章

  1. 分布式事务与Seate框架(3)——Seata的AT模式实现原理

    前言 在上两篇博文(分布式事务与Seate框架(1)--分布式事务理论.分布式事务与Seate框架(2)--Seata实践)中已经介绍并实践过Seata AT模式,这里一些例子与概念来自这两篇(特别是 ...

  2. 阿里神器 Seata 实现 TCC模式 解决分布式事务,真香!

    今天这篇文章介绍一下Seata如何实现TCC事务模式,文章目录如下: 什么是TCC模式? TCC(Try Confirm Cancel)方案是一种应用层面侵入业务的两阶段提交.是目前最火的一种柔性事务 ...

  3. 深入浅出AQS之共享锁模式

    在了解了AQS独占锁模式以后,接下来再来看看共享锁的实现原理. 原文地址:http://www.jianshu.com/p/1161d33fc1d0 搞清楚AQS独占锁的实现原理之后,再看共享锁的实现 ...

  4. 深入浅出设计模式——简单工厂模式(Simple Factory)

    介绍简单工厂模式不能说是一个设计模式,说它是一种编程习惯可能更恰当些.因为它至少不是Gof23种设计模式之一.但它在实际的编程中经常被用到,而且思想也非常简单,可以说是工厂方法模式的一个引导,所以我想 ...

  5. 深入浅出设计模式——工厂方法模式(Factory Method)

    介绍在简单工厂模式中,我们提到,工厂方法模式是简单工厂模式的一个延伸,它属于Gof23中设计模式的创建型设计模式.它解决的仍然是软件设计中与创建对象有关的问题.它可以更好的处理客户的需求变化. 引入我 ...

  6. 深入浅出设计模式——抽象工厂模式(Abstract Factory)

    模式动机在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法.但是有时候我们需要一个工厂可 ...

  7. 深入浅出设计模式——享元模式(Flyweight Pattern)

    模式动机 面向对象技术可以很好地解决一些灵活性或可扩展性问题,但在很多情况下需要在系统中增加类和对象的个数.当对象数量太多时,将导致运行代价过高,带来性能下降等问题.享元模式正是为解决这一类问题而诞生 ...

  8. 深入浅出设计模式——职责链模式(Chain of Responsibility Pattern)

    模式动机 职责链可以是一条直线.一个环或者一个树形结构,最常见的职责链是直线型,即沿着一条单向的链来传递请求.链上的每一个对象都是请求处理者,职责链模式可以将请求的处理者组织成一条链,并使请求沿着链传 ...

  9. 深入浅出设计模式——中介者模式(Mediator Pattern)

    模式动机 在用户与用户直接聊天的设计方案中,用户对象之间存在很强的关联性,将导致系统出现如下问题: 系统结构复杂:对象之间存在大量的相互关联和调用,若有一个对象发生变化,则需要跟踪和该对象关联的其他 ...

  10. linux(centos8):安装分布式事务服务seata(file单机模式,seata 1.3.0/centos 8.2)

    一,什么是seata? Seata:Simpe Extensible Autonomous Transcaction Architecture, 是阿里中间件,开源的分布式事务解决方案. 前身是阿里的 ...

随机推荐

  1. 示例:Service连接应用程序

    整体思路: 1.创建pod 2.创建关联上一步pod的service 3.使用不同的方式配置service从而能够在集群内部访问 4.使用ssl方式加密访问service 5.配置service为no ...

  2. MySQL手动恢复数据库测试操作

    事件背景 MySQL数据库每日零点自动全备 某天上午9点,二狗子不小心drop了一个数据库 我们需要通过全备的数据文件,以及增量的binlog文件进行数据恢复 主要思想与原理 利用全备的sql文件中记 ...

  3. 【Java8新特性】- 接口中默认方法修饰为普通方法

    Java8新特性 - 接口中默认方法修饰为普通方法 生命不息,写作不止 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学 ...

  4. IDEA上关于 jstl导包的问题

    IDEA上关于 jstl的问题 在 IDEA上使用 maven创建 web骨架项目,在 pom文件中添加 jstl依赖 <dependency> <groupId>jstl&l ...

  5. 【博学谷学习记录】超强总结,用心分享|MySql连接查询超详细总结

    一.概述 在实际开发中,大部分情况下都不是在单表中进行数据操作,一般都是多张表进行联合查询.通常一个业务就会对应的有好几张表.MySql中的连接查询分为交叉连接,内连接,外连接三部分.其中交叉连接也叫 ...

  6. Java中的反射与代理(2)

    在经典的GoF设计模式中,有一种模式叫做代理模式,好比以前洋务运动的时候所说的「买办」,还有现在咱们经常听到的「代理人」战争中的「代理」,都是同一个意思--代替某人打理. 例如,很多北漂都找中介或者二 ...

  7. JS---HelloWorld

    1.功能效果图 2.代码实现 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> ...

  8. springboot+bootstrap实现图书商城管理(大三下学期课程设计)

    在csdn上记一次自己的课程设计过程(已经实习两个月了.感觉这个很容易做.支付可能需要多花点时间.): 在此框架基础之上权限认证管理设置成功:https://blog.csdn.net/weixin_ ...

  9. 2022HNCTF--WEB

    @ 目录 [Week1]Interesting_http 分析 payload [Week1]2048 分析 payload [Week1]easy_html 分析 paylaod [Week1]In ...

  10. pycharm系列---django

    manage debug Python Console基本配置 DJANGO_SETTINGS_MODULE=mini_project.settings import sys import djang ...