Seata客户端@GlobalTransactional核心源码解析

文章目录

  • 前言
  • 一、@GlobalTransactional
    • 1.1、wrapIfNecessary
    • 1.2、handleGlobalTransaction
    • 1.3、invoke
  • 二、总结


前言

  Seata是阿里开源的分布式事务解决方案。在Spring传统的事务中,开启事务,执行事务,回滚/提交事务,统一由Spring进行管理,向数据库发起指令。而分布式事务中,分为了客户端(微服务端)和服务端(Seata)、注册中心(通常使用Nacos)这三个部分。Nacos提供了服务注册与发现,以及管理Seata配置的作用。无论是开启事务,执行事务,还是提交事务,都不是单个微服务内部自己决定的,而是统一向服务端发起请求,由服务端进行一系列的处理后,再向微服务端发起请求,驱动微服务端执行操作。


一、@GlobalTransactional

  对于微服务端,通常会在分布式事务的入口方法,加上@GlobalTransactional注解,表示该服务在分布式事务中作为TM的角色。微服务端的源码解析,自然要从该注解开始。
  在注解的注释上,标注了三个关键方法:
在这里插入图片描述

1.1、wrapIfNecessary

  使用Seata,在微服务端需要引入一个依赖:

        <!-- seata--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId></dependency>

  通过自动配置机制,可以找到Seata客户端的核心类:
在这里插入图片描述
  在这个类中,装配了两个Bean:

  • FailureHandler:用于处理事务开始,执行,提交/回滚失败的情况,留给子类实现,发送邮件或通知告警。默认的实现DefaultFailureHandlerImpl则是进行日志记录。
  • GlobalTransactionScanner:是Seata的全局事务扫描器。

在这里插入图片描述
  GlobalTransactionScanner继承自AbstractAutoProxyCreator,重写了其关键方法wrapIfNecessary
在这里插入图片描述
  在wrapIfNecessary方法中,首先会判断当前模式是否为TCC,如果是TCC模式,创建TccActionInterceptor拦截器并设置清理任务,同时监听配置中心的开关DISABLE_GLOBAL_TRANSACTION
在这里插入图片描述
  否则就是AT模式,会检查目标类上是否存在@GlobalTransactional或方法上是否存在@GlobalTransactional@GlobalLock注解,如果存在,使用GlobalTransactionalInterceptor来代理。
在这里插入图片描述
  因为GlobalTransactionalInterceptor实现了MethodInterceptor接口,所以将创建出的GlobalTransactionalInterceptor实例赋值给MethodInterceptor类型的interceptor属性:
在这里插入图片描述


  判断是否存在@GlobalTransactional@GlobalLock注解,这一步非常关键,如果判断不通过,该类就不会做和Seata有关的增强。
在这里插入图片描述
existsAnnotation


  如果该Bean没有被代理过,则调用父类方法创建代理。如果已经是AOP代理,则动态插入Seata的Advisor。
在这里插入图片描述
  在super.wrapIfNecessary中,有一行关键代码getAdvicesAndAdvisorsForBean,目的是获取该 bean 适用的增强(Advice)或拦截器(Advisor),在Seata中选择图上的实现:

在这里插入图片描述
  如果是普通全局事务,就使用GlobalTransactionalInterceptor增强目标方法,执行其invoke方法。

在这里插入图片描述

wrapIfNecessary方法在Spring启动时,判断是否需要为 Bean 创建事务代理,并注入相应的拦截器(TCC 或 AT 模式)。

1.2、handleGlobalTransaction

  在1.1中,创建了GlobalTransactionalInterceptor的对象,其实现了MethodInterceptor
在这里插入图片描述
  在重写了MethodInterceptorinvoke方法中,如果当前方法上存在@GlobalTransactional注解,则会调用到handleGlobalTransaction方法:
在这里插入图片描述
  在handleGlobalTransaction方法中,首先会执行transactionalTemplateexecute方法:
在这里插入图片描述
  在执行execute方法的过程中,可能会发生异常,handleGlobalTransaction捕捉到异常后,会进行判断,如果当前是事务的参与者,也就是RM,则继续向上抛出异常,如果是事务的发起者TM,则解析出异常的code,执行各自失败的逻辑(SeataAutoConfiguration中注入的FailureHandler的逻辑)。
在这里插入图片描述
  这里的TransactionalTemplate,是seata的实现:在这里插入图片描述
  在execute方法中,首先会进行事务传播级别的判断,是否应该新开启一个事务,挂起当前事务等操作:Seata 的传播级别与 Spring 的传播语义一致,但实现机制完全不同,Spring 操作本地事务,Seata 操作的是全局分布式事务上下文。

在这里插入图片描述
  然后就会执行一套标准的事务流程:开启事务,执行事务,提交/回滚。
在这里插入图片描述

handleGlobalTransaction 方法代表了事务执行的整体流程。

1.3、invoke

  invoke是在AOP拦截到对原始DataSource的调用时,将调用路由到Seata的代理DataSource上,使得数据库连接支持全局事务的上下文控制。

  1. 判断拦截的方法是否为javax.sql.DataSource接口中定义的方法。
  2. 获取当前原始的DataSource,从DataSourceProxyHolde中获取其对应的SeataDataSourceProxy,最终将方法调用代理到 SeataDataSourceProxy 上。

在这里插入图片描述

Seata 使 SeataDataSourceProxy来增强连接的行为,如记录 UndoLog,绑定 XID,向 TC 注册分支事务

二、总结

Spring 容器启动时

  • GlobalTransactionScanner 会扫描所有 bean 的方法是否包含@GlobalTransactional@GlobalLock注解。
  • 如果有,就为该方法添加一个 AOP Advisor,代理增强逻辑就是 GlobalTransactionalInterceptor

方法执行时

  • Spring AOP 会调用 GlobalTransactionalInterceptor#invoke()
  • Seata 会根据事务传播级别、当前事务上下文,决定是否发起或加入全局事务。
  • 正常执行业务逻辑(调用 invocation.proceed())。
  • 执行完毕后:
    • 如果方法正常返回,Seata 提交全局事务;
    • 如果方法抛出异常,Seata 回滚事务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/79212.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/79212.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytorch搭建并训练神经网络

#从小白开始学习人工智能# #学习笔记# 工具&#xff1a;pytorch 一、基础概念 1.神经网络是什么&#xff1f; 神经网络是人类受到生物神经细胞结构启发而研究出的算法体系。又称为人工神经网络&#xff08;Artificial neural network&#xff09; 最简版神经网络结构图&a…

JavaEE-多线程实战01

Java 多线程入门&#xff1a;第一个多线程程序 在 Java 中&#xff0c;多线程编程是非常重要的一部分。本篇文章将通过示例&#xff0c;带你快速了解如何创建第一个多线程程序&#xff0c;并深入分析其运行机制。 1. 创建一个线程类并继承 Thread 在 Java 中&#xff0c;我们…

Android Compose 无网络状态处理全指南:从基础到高级实践

Android Compose 无网络状态界面处理全方案 引言 在移动应用开发中&#xff0c;网络连接不稳定是常见场景。优雅地处理无网络状态能显著提升用户体验。Jetpack Compose 提供了强大的工具来实现各种网络状态下的界面展示。本文将全面介绍在 Compose 中处理无网络状态的多种方案…

Arduino项目实战与编程技术详解

一、智能避障小车:超声波传感器与PWM电机控制 1.1 硬件需求与工作原理 智能避障小车的核心在于超声波传感器与电机驱动模块的协同工作。超声波传感器(HC-SR04)通过发射高频声波并接收回波来测量距离,而L298N电机驱动模块则负责控制两个直流电机的转向与速度。 1.1.1 超声…

Java在云计算、大数据、云原生下的应用和优势 - 面试实战

Java在云计算、大数据、云原生下的应用和优势 - 面试实战 第一轮提问 面试官&#xff1a;马架构&#xff0c;请简单介绍一下Java在云计算中的主要应用场景有哪些&#xff1f; 马架构&#xff1a;Java在云计算中的主要应用场景包括微服务架构设计、容器化部署&#xff08;如D…

数据库与大数据技术教程资料

概述 无论你是刚入门的技术新人&#xff0c;还是寻求突破的资深工程师&#xff0c;这份精心整理的电子书合辑将为你打开系统性学习的大门&#xff01;所有资源支持多端阅读&#xff0c;助力技术成长每一步资料已经整理好&#xff0c;喜欢的朋友请自取&#xff1a;https://pan.…

【Spring Boot 注解】@ConfigurationProperties

文章目录 ConfigurationProperties注解一、简介二、依赖引入三、基本用法四、主要特性五、激活方式六&#xff0c;优点七、与 Value 对比 ConfigurationProperties注解 一、简介 ConfigurationProperties 是 Spring Boot 提供的一个强大注解&#xff0c;用于将外部配置&#…

C++(初阶)(十六)——set

set setset介绍set的构造和迭代器set的增删查findlower_boundmultiset和set的差异 题目[349. 两个数组的交集 - 力扣&#xff08;LeetCode&#xff09;](https://leetcode.cn/problems/intersection-of-two-arrays/description/)交集差集[142. 环形链表 II - 力扣&#xff08;L…

higress之:让流量通过gateway

本来想测跨域问题&#xff0c;结果参数配置过去之后一直没生效&#xff0c;经过了解说是gateway才是设置跨域参数的核心&#xff0c;所以需要让流量通过gateway&#xff0c;捣鼓了半天记录一下 第一步&#xff0c;测试服务是否正常 通过get svc、pod等&#xff0c;发现各pod都…

C盘哪些文件删除之后无影响,可以清理磁盘空间。

C盘是电脑的系统盘,存放了操作系统的重要文件和部分默认安装的软件。当C盘空间不足时,系统可能运行缓慢甚至卡顿,这时清理C盘是一个有效的解决方法。由于C盘包含许多关键数据,清理时需要格外谨慎,以免误删导致系统崩溃。将详细介绍C盘中可以安全删除的文件类型及清理方法,…

开源项目实战学习之YOLO11:ultralytics-cfg-models-fastsam(九)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 1. __init__.py2. model.py3. predict.py4. utils.py5. val.py FastSAM 是一种目标检测和图像分割模型&#xff0c;Ultralytics 是一个在计算机视觉领域广泛使用的库&#x…

Windows11安装Docker

本次安装环境 Windows11&#xff08;23H2&#xff09;&#xff0c;CPU&#xff08;12代Intel&#xff09; 什么是Docker Docker 是一个软件平台&#xff0c;让您可以快速构建、测试和部署应用程序。Docker 将软件打包成名为容器的标准化单元&#xff0c;这些单元具有运行软件所…

C# 在VS2022中开发常用设置

一、基础环境配置 1. 安装必要组件 在 VS2022 安装时确保勾选以下工作负载&#xff1a; ​​使用 .NET 的桌面开发​​&#xff08;包含 WPF/WinForms&#xff09;​​ASP.NET 和 Web 开发​​​​.NET 跨平台开发​​​​Azure 开发​​​​数据存储和处理​​ 2. 主题与外…

k8s的volume

一、volume介绍 volume是Pod中能够呗多个容器访问的共享目录。Kubernetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价。首先,Kubernetes中的Volume定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;其次,Kubernetes中的Volume与Pod的生…

Java 未来技术栈:从云原生到 AI 融合的企业级技术演进路线

一、云原生架构&#xff1a;重构 Java 应用的运行范式 1.1 微服务架构的深度进化 Java 在微服务领域的实践正从 Spring Cloud 向服务网格&#xff08;Service Mesh&#xff09;演进。以 Istio 为代表的服务网格技术&#xff0c;通过 Sidecar 模式实现服务间通信的透明化管理&…

阿里云 ECS 服务器进阶指南:存储扩展、成本优化与架构设计

一、弹性存储架构&#xff1a;块存储深度解析与挂载实践 &#xff08;一&#xff09;块存储类型与技术特性 阿里云块存储作为 ECS 核心存储方案&#xff0c;提供三种主流类型&#xff1a; ESSD 云盘 性能等级&#xff1a;PL0/PL1/PL2/PL3&#xff0c;最高支持 100 万 IOPS …

centos 安装jenkins

centos 安装jenkins 在 CentOS 上安装 Jenkins 是一个相对直接的过程。以下是一个逐步指南&#xff0c;帮助你安装 Jenkins&#xff1a; 步骤 1&#xff1a;安装 Java Jenkins 需要 Java 运行环境&#xff0c;因此首先确保你的系统上安装了 Java。你可以使用以下命令来安装 …

十三种物联网/通信模块综合对比——《数据手册--物联网/通信模块》

物联网&#xff0f;通信模块 名称 功能 应用场景 USB转换模块 用于将USB接口转换为其他类型的接口&#xff0c;如串口、并口等&#xff0c;实现不同设备之间的通信。 常用于计算机与外部设备&#xff08;如打印机、扫描仪等&#xff09;的连接&#xff0c;以及数据传输和设…

【基础知识】常见的计算公式(二)

目录标题 一、ADC&#xff08;模拟 - 数字转换器&#xff09;相关公式1. ADC 分辨率计算2. ADC 转换结果对应的模拟电压计算 二、DAC&#xff08;数字 - 模拟转换器&#xff09;相关公式1. DAC 输出电压计算 三、SPI&#xff08;串行外设接口&#xff09;相关公式1. SPI 数据传…

DeepSeek V1:初代模型的架构与性能

DeepSeek V1(又称DeepSeek-MoE)是DeepSeek系列的首代大规模语言模型,它采用Transformer结合稀疏混合专家(MoE)的创新架构,实现了在受控算力下的大容量模型。本文将深入解析DeepSeek V1的架构设计与技术细节,包括其关键机制、训练优化策略,以及在各类NLP任务上的表现。 …