分布式事务学习笔记(四)微服务实现Stata AT模式、Stata Saga模式介绍

server/2024/9/22 22:53:10/

文章目录

  • 前言
  • 4 Seata AT 模式
    • 4.1 实现原理
    • 4.2 脏写问题
    • 4.3 微服务实现AT模式
      • 4.3.1 新建数据库表
      • 4.3.2 修改配置文件
      • 4.3.3 重启服务并测试
  • 5 Seata Saga 模式

前言

分布式事务学习笔记(一)分布式事务问题、CAP定理、BASE理论、Seata
分布式事务学习笔记(二)Seata架构、TC服务器部署、微服务集成Seata
分布式事务学习笔记(三)微服务实现Seata XA模式

Seata_AT__7">4 Seata AT 模式

AT 模式同样是分阶段提交的非侵入式分布式事务模型,不过弥补了 XA 模式中资源锁定周期过长的缺陷。

4.1 实现原理

  • 第一阶段RM的工作
    • 向TC注册分支事务
    • 执行业务SQL并直接提交
    • 记录更新前后快照(undo-log)
    • 向TC报告分支事务状态
  • 第二阶段RM的工作
    • 如果收到TC确认提交的指令,则删除快照(undo-log)
    • 如果收到TC确认回滚的指令,则根据快照(undo-log)恢复数据到更新前

其中,记录更新前后快照(undo-log) 是RM拦截业务SQL,根据业务SQL的where条件查询原始数据,并保存起来形成快照。后续需要回滚时,可以根据这个快照直接恢复。

  • 与 XA 模式的比较
XA模式AT模式
事务特性第一阶段不提交事务,锁定资源第一阶段提交事务,不锁定资源
回滚机制依赖数据库机制实现回滚利用数据快照实现数据回滚
一致性强一致最终一致

4.2 脏写问题

在多线程并发访问AT模式分布式事务时,有可能出现脏写问题,如图:

问题出现的关键原因在于,当前事务根据快照回滚之前,有另外一个事务也操作了当前数据,使得当前事务的快照不再正确。

解决脏写问题的思路就是引入了全局锁的概念。

事务在释放DB锁之前,先拿到全局锁,只有拿到全局锁的事务有资格操作当前数据,从而避免同一时刻有另外一个事务来操作当前数据,如图:

由上图可知,事务1持有全局锁,具备执行权。而事务2拿不到全局锁,则无法操作当前数据。事务1进行回滚时则不会有影响。

AT模式优点在于:

  • 第一阶段完成后直接提交事务,释放数据库资源,性能比较好
  • 利用全局锁实现读写隔离
  • 没有代码侵入,框架自动完成回滚和提交

AT模式缺点在于:

  • 两阶段之间属于软状态,属于最终一致
  • 框架的快照功能会影响性能,但比XA模式要好很多

4.3 微服务实现AT模式

4.3.1 新建数据库表

AT模式中的快照生成、回滚等动作都是由框架自动完成,没有任何代码侵入,实现简单。但AT模式需要 lock_table 表来记录全局锁、undo_log 表来记录数据快照。

在学习 XA 模式时,就已经创建了 lock_table 表,而创建 undo_log 表的SQL可以在 https://gitee.com/seata-io/seata/blob/v1.5.1/script/client/at/db/mysql.sql 中找到:

-- for AT mode you must to init this sql for you business database. the seata server not need it.
CREATE TABLE IF NOT EXISTS `undo_log`
(`branch_id`     BIGINT       NOT NULL COMMENT 'branch transaction id',`xid`           VARCHAR(128) NOT NULL COMMENT 'global transaction id',`context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',`rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',`log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',`log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',`log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDBAUTO_INCREMENT = 1DEFAULT CHARSET = utf8mb4 COMMENT ='AT transaction mode undo table';

4.3.2 修改配置文件

修改微服务的application.yml文件,将事务模式修改为AT模式即可:

seata:data-source-proxy-mode: AT # 默认就是AT

4.3.3 重启服务并测试

假设现在商品库存为10,用户余额为1000。用户使用300金额购买了6件商品:

程序执行到这里,已经扣除用户余额成功。而在 undo_log 表中记录了金额的快照:

程序继续执行,下单成功,undo_log 表的记录被删除:

假设此时用户再次使用300金额购买了6件商品,由于此时库存只剩下4件,所以会下单失败:

jd-account-service服务的日志显示,余额先是扣除成功,而后被回滚:

最终余额和库存均没有改变:

可见AT模式分布式事务已生效。

Seata_Saga__125">5 Seata Saga 模式

Saga 模式是 Seata 提供的长事务解决方案。其工作流程如下:

在该模式中,分布式事务内有多个参与者,每一个参与者都有一个正向服务和一个补偿服务,需要用户根据业务场景分别实现其正向操作和逆向回滚操作。

分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会去执行前面各参与者的补偿服务,回滚已提交的操作,使分布式事务回到初始状态。

因此,Saga 模式也分为两个阶段:

  • 一阶段:各参与者直接提交本地事务
  • 二阶段:均成功则什么都不做;有任意失败则通过补偿服务来回滚

Saga 模式的优点

  • 事务参与者可以基于事件驱动实现异步调用,吞吐高
  • 一阶段直接提交事务,无锁,性能好

缺点

  • 软状态持续时间不确定,时效性差
  • 没有锁,没有事务隔离,会有脏写

本节完,更多内容请查阅分类专栏:微服务学习笔记

感兴趣的读者还可以查阅我的另外几个专栏:

  • SpringBoot源码解读与原理分析
  • MyBatis3源码深度解析
  • Redis从入门到精通
  • MyBatisPlus详解
  • SpringCloud学习笔记

http://www.ppmy.cn/server/120007.html

相关文章

链路追踪在分布式项目中有什么作用?

文章目录 请求追踪性能分析故障排查服务依赖关系分析全链路监控数据驱动的决策支持常用链路追踪工具 链路追踪(Link Tracking 或 Distributed Tracing)是一种用于监控和观察分布式系统中的请求流动和性能的技术。在现代微服务架构中,特别是涉…

云服务器和物理服务器的区别在哪

在当今数字化的时代,服务器在企业和个人的信息技术架构中扮演着至关重要的角色。其中,云服务器和物理服务器是两种主要的服务器类型,它们在多个方面存在着明显的区别。 一、硬件方面 物理服务器是实实在在的物理硬件设备,它由机…

markdown-it:将Markdown文本转换为HTML格式,展示在页面,怎么自定义里面的a标签设置为在新标签页打开

由markdown-it将文本生成html然后渲染到页面上,但是现在你点击里面生成好的链接只能在本标签页打开,怎么将其设置为在新标签打开呢? 安装markdown-it npm install markdown-it 使用markdown-it const mdi new MarkdownIt({html: true,l…

springboot+redis+缓存

整合 添加依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 连接redis&#xff0c;配置yml文件 主机 端口号 数据库是哪一个 密码 配置类 p…

MySQL5.7中增加的JSON特性的处理方法JSON_EXTRACT和JSON_ARRAY_APPEND以及MYSQL中JSON操作的方法大全

一、MySQL5.7中增加的JSON特性的处理方法JSON_EXTRACT和JSON_ARRAY_APPEND 数据库中有些字段的存储可能是json字符串&#xff0c;在MYSQL5.7之前直接使用sql不好操作&#xff0c;但在mysql5.7中增加了对json处理的一些函数&#xff0c;比如JSON_EXTRACT分解JSON 并查询以及JSON…

【d44】【Java】【力扣】160.相交链表

思路 先把a链表都放进 一个hashSet集合 再遍历B链表&#xff0c;逐个放进hashSet集合 如果无法放进&#xff0c;说明这个节点就是相交节点 代码 import java.util.HashSet;public class Main {public static void main(String[] args) {}public class ListNode {int val;Li…

HarmonyOS开发者基础认证试题

文章目录 一、HarmonyOS介绍二、DevEco Studio的使用三、ArkTS语法介绍四、应用程序框架基础五、从简单的页面开始六、构建更加丰富的页面七、从网络获取数据八、保存应用数据 一、HarmonyOS介绍 判断题&#xff1a; 1.“一次开发&#xff0c;多端部署”指的是一个工程&#x…

安卓玩机工具-----多设备同时投屏操控的安卓手机设备投屏工具 工作室推荐

多设备QtScrcpy投屏工具 对于安卓设备较多的机型。在电脑端实时操作必备工具。他可以同时投屏连接到当前电脑端的安卓设备&#xff0c;而且可以同时操作。对于工作室或者多安卓设备玩家推荐使用。 工具特点 QtScrcpy是一款在Scrcpy的基础上新增功能的安卓手机投屏工具&#xff…