微服务:分布式事务

devtools/2024/12/22 13:05:35/

💥 该系列属于【SpringBoot基础】专栏,如您需查看其他SpringBoot相关文章,请您点击左边的连接

目录

一、引言

二、Seata

三、部署TC服务

1. 准备数据库表

2. 准备配置文件 

3. Docker部署

四、微服务集成Seata

1. 引入依赖

2. 改造配置

3. 启动项目,观察日志

五、XA模式

1. Seata的XA模式

2. 实现

六、AT模式

1. Seata的AT模式

2. AT模式与XA模式最大的区别是什么?

3. 实现


一、引言

分布式系统中,如果一个业务需要多个服务合作完成,而且每一个服务都有事务,多个事务必须同时成功或失败,这样的事务就是分布式事务。其中的每个服务的事务就是一个分支事务。整个业务称为全局事务。

参与事务的多个子业务在不同的微服务,跨越了不同的数据库。虽然每个单独的业务都能在本地遵循ACID,但是它们互相之间没有感知,不知道有人失败了,无法保证最终结果的统一,也就无法遵循ACID的事务特性了。 

现以下情况之一就可能产生分布式事务问题:

  • 业务跨多个服务实现

  • 业务跨多个数据源实现

二、Seata

在众多的开源分布式事务框架中,功能最完善、使用最多的就是阿里巴巴在2019年开源的Seata了。

在Seata的事务管理中有三个重要的角色:

  • TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚。

  • TM (Transaction Manager) - 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。

  • RM (Resource Manager) - 资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。

Seata的工作架构如图所示:

其中,TMRM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TMRM就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。

TC服务则是事务协调中心,是一个独立的微服务,需要单独部署。

三、部署TC服务

1. 准备数据库表

Seata支持多种存储模式,但考虑到持久化的需要,我们一般选择基于数据库存储。执行提前准备的seata-tc.sql,导入数据库表:

2. 准备配置文件 

准备了一个seata目录,其中包含了seata运行时所需要的配置文件:

将整个seata文件夹拷贝到虚拟机的/root目录:

3. Docker部署

在虚拟机的/root目录执行下面的命令:

docker run --name seata \
-p 8099:8099 \
-p 7099:7099 \
-e SEATA_IP=192.168.88.128 \
-v /root/seata:/seata-server/resources \
--privileged=true \
--network hmall \
-d \
seataio/seata-server:1.5.2

确保mysql,nacos和seata再同一个network hmall之下

四、微服务集成Seata

1. 引入依赖

为了方便各个微服务集成seata,我们需要把seata配置共享到nacos,因此item-service, cart-service和trade-service模块不仅仅要引入seata依赖,还要引入nacos依赖:

<!--统一配置管理--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency><!--读取bootstrap文件--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bootstrap</artifactId></dependency><!--seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>

2. 改造配置

在nacos上添加一个共享的seata配置,命名为shared-seata.yaml

然后,改造hm-trade,hm-cart和hm-item两个微服务模块:bootstrap.yaml

spring:application:name: trade-service # 服务名称profiles:active: devcloud:nacos:server-addr: 192.168.150.101 # nacos地址config:file-extension: yaml # 文件后缀名shared-configs: # 共享配置- dataId: shared-jdbc.yaml # 共享mybatis配置- dataId: shared-log.yaml # 共享日志配置- dataId: shared-swagger.yaml # 共享日志配置- dataId: shared-seata.yaml # 共享seata配置

3. 启动项目,观察日志

docker logs -f seata 

集成seata成功。 

五、XA模式

1. Seata的XA模式

Seata对原始的XA模式做了简单的封装和改造,以适应自己的事务模型,基本架构如图:

RM一阶段的工作:

  1. 注册分支事务到TC

  2. 执行分支业务sql但不提交

  3. 报告执行状态到TC

TC二阶段的工作:

  1. TC检测各分支事务执行状态

    1. 如果都成功,通知所有RM提交事务

    2. 如果有失败,通知所有RM回滚事务

RM二阶段的工作:

  • 接收TC指令,提交或回滚事务

XA模式的优点是什么?

  • 事务的强一致性,满足ACID原则

  • 常用数据库都支持,实现简单,并且没有代码侵入

XA模式的缺点是什么?

  • 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差

  • 依赖关系型数据库实现事务

2. 实现

首先,我们要在配置文件中指定要采用的分布式事务模式。我们可以在Nacos中的共享shared-seata.yaml配置文件中设置:

seata:data-source-proxy-mode: XA

其次,我们要利用@GlobalTransactional标记分布式事务的入口方法:

六、AT模式

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

1. Seata的AT模式

阶段一RM的工作:

  • 注册分支事务

  • 记录undo-log(数据快照)

  • 执行业务sql并提交

  • 报告事务状态

阶段二提交时RM的工作:

  • 删除undo-log即可

阶段二回滚时RM的工作:

  • 根据undo-log恢复数据到更新前

2. AT模式与XA模式最大的区别是什么?

简述AT模式与XA模式最大的区别是什么?

  • XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。

  • XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。

  • XA模式强一致;AT模式最终一致

可见,AT模式使用起来更加简单,无业务侵入,性能更好。因此企业90%的分布式事务都可以用AT模式来解决。

3. 实现

微服务对应的数据库中创建快照表undo_log:

-- 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';

执行结果: 

 在Nacos中的共享shared-seata.yaml配置文件中设置:(也可以不写,因为AT是默认值)

seata:data-source-proxy-mode: AT

 其次,我们要利用@GlobalTransactional标记分布式事务的入口方法:

 

 


http://www.ppmy.cn/devtools/97885.html

相关文章

【企业高性能web服务器】

目录 一、Nginx 介绍1、 Nginx 功能介绍2、基础特性3、Nginx 模块介绍 二、Nginx 编译安装1、编写systemd服务 三、平滑升级和回滚1、平滑升级的流程2、升级2、回滚 四、 Nginx 核心配置详解1、实现 nginx 的高并发配置2、Nginx 账户认证功能3、nginx作为下载服务器配置 五、re…

【K8s】专题十二(1):Kubernetes 存储简介

本文内容均来自个人笔记并重新梳理&#xff0c;如有错误欢迎指正&#xff01; 如果对您有帮助&#xff0c;烦请点赞、关注、转发、订阅专栏&#xff01; 专栏订阅入口 Linux 专栏 | Docker 专栏 | Kubernetes 专栏 往期精彩文章 【Docker】&#xff08;全网首发&#xff09;Kyl…

“双指针”算法上篇

『 你 的 名 字 』高帧4K动漫素材&#xff0c;无水印&#xff0c;需要自取&#xff01; 题目&#xff1a; 一 移动零 1.题目链接&#xff1a;移动零 2. 分析 解法一&#xff1a;暴力求解 就是新开一个数组&#xff0c;大小与原数组大小一致&#xff0c;只要不是数字0就进行…

(四)Flink Transformation 数据转换

用户通过算子能将一个或多个 DataStream 转换成新的 DataStream,在应用程序中可以将多个数据转换算子合并成一个复杂的数据流拓扑。 这部分内容将描述 Flink DataStream API 中基本的数据转换 API。 目录 Map(DataStream → DataStream) FlatMap(DataStream → DataStre…

【前端面试】javascript全栈开发——深挖nestJS项目

注意区别于nextJS框架——web全栈应用框架。 NestJS NestJS 是一个现代的、用于构建可扩展的 Node.js 服务器端应用程序的框架,它使用 TypeScript 构建,结合了 OOP、FP 和 FRP (详见下面)。 NestJS 提供了一个开箱即用的应用架构,允许开发者和团队创建高度可测试、可扩展、…

Compose(11)APT阶段的任务

在 Android 开发中&#xff0c;使用 Jetpack Compose 的声明式 UI 在编译的 APT&#xff08;Annotation Processing Tool&#xff0c;注解处理工具&#xff09;阶段可能会进行以下一些操作&#xff1a; 一、生成代码 可组合函数分析&#xff1a; APT 可以分析开发者编写的可组…

代理模式:静态代理和动态代理

目录 一、静态代理 1、优点 2、 缺点 3、示例 二、动态代理 1、优点 2、 缺点 3、示例 三、总结 在Java中&#xff0c;代理模式是一种结构型设计模式&#xff0c;它允许你在不改变目标对象代码的情况下&#xff0c;为目标对象提供一个代理对象&#xff0c;用以控制访问和增强功…

别再无效清理微信内存啦,这才是正确清理内存的方式

微信作为我们日常生活中必不可少的社交工具&#xff0c;随着时间的积累&#xff0c;往往会占据手机大量宝贵的存储空间。 如何在保证重要信息不丢失的同时&#xff0c;有效地管理和清理微信中的垃圾文件和无用数据&#xff0c;成为了一个值得探讨的话题。 本文将从几个方面介…