一篇文章介绍分布式事务

news2024/9/21 4:30:59

1、事务的基本概念

  • 事务

事务指的就是一个操作单元,在这个操作单元中的所有操作最终要保持一致的行为,要么所有操作都成功,要么所有的操作都被撤销。简单地说,事务提供一种“要么什么都不做,要么做全套”机制。

  • 本地事务

本地事务其实可以认为是数据库提供的事务机制。说到数据库事务就不得不说,数据库事务中的四大特性:
A:原子性(Atomicity),一个事务中的所有操作,要么全部完成,要么全部不完成
C:一致性(Consistency),在一个事务执行之前和执行之后数据库都必须处于一致性状态
I:隔离性(Isolation),在并发环境中,当不同的事务同时操作相同的数据时,事务之间互不影响
D:持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久的保存下来

数据库事务在实现时会将一次事务涉及的所有操作全部纳入到一个不可分割的执行单元,该执行单元中的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都将导致整个事务的回滚。

  • 分布式事务

分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。

简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。

本质上来说,分布式事务就是为了保证不同数据库的数据一致性

  • 分布式事务的场景

a、单体系统访问多个数据库

一个服务需要调用多个数据库实例完成数据的增删改操作

b、多个微服务访问同一个数据库
多个服务需要调用一个数据库实例完成数据的增删改操作

c、多个微服务访问多个数据库
多个服务需要调用多个数据库实例完成数据的增删改操作

2、分布式事务解决方案


全局事务

全局事务基于DTP模型实现。DTP是由X/Open组织提出的一种分布式事务模型——X/Open Distributed Transaction Processing Reference Model。它规定了要实现分布式事务,需要三种角色:

AP: Application 应用系统 (微服务)

TM: Transaction Manager 事务管理器 (全局事务管理)

RM: Resource Manager 资源管理器 (数据库)

整个事务分成两个阶段:

阶段一: 表决阶段,所有参与者都将本事务执行预提交,并将能否成功的信息反馈发给协调者。

阶段二: 执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地执行提交或者回滚。

优点:提高了数据一致性的概率,实现成本较低

缺点:

单点问题:事务协调者宕机

同步阻塞: 延迟了提交时间,加长了资源阻塞时间

数据不一致: 提交第二阶段,依然存在commit结果未知的情况,有可能导致数据不一致

可靠消息服务


基于可靠消息服务的方案是通过消息中间件保证上、下游应用数据操作的一致性。
假设有A和B两个系统,分别可以处理任务A和任务B。此时存在一个业务流程,需要将任务A和任务B在同一个事务中处理。就可以使用消息中间件来实现这种分布式事务。

第一步: 消息由系统A投递到中间件

在系统A处理任务A前,首先向消息中间件发送一条消息

消息中间件收到后将该条消息持久化,但并不投递。持久化成功后,向A回复一个确认应答

系统A收到确认应答后,则可以开始处理任务A

任务A处理完成后,向消息中间件发送Commit或者Rollback请求。该请求发送完成后,对系统A而言,该事务的处理过程就结束了

如果消息中间件收到Commit,则向B系统投递消息;如果收到Rollback,则直接丢弃消息。但是如果消息中间件收不到Commit和Rollback指令,那么就要依靠"超时询问机制"。

超时询问机制 系统A除了实现正常的业务流程外,还需提供一个事务询问的接口,供消息中间件调用。当消息中间件收到发布消息便开始计时,如果到了超时没收到确认指令,就会主动调用系统A提供的事务询问接口询问该系统目前的状态。该接口会返回三种结果,中间件根据三种结果做出不同反应:

提交:将该消息投递给系统B

回滚:直接将条消息丢弃

处理中:继续等待

第二步: 消息由中间件投递到系统B

消息中间件向下游系统投递完消息后便进入阻塞等待状态,下游系统便立即进行任务的处理,任务处理完成后便向消息中间件返回应答。

如果消息中间件收到确认应答后便认为该事务处理完毕

如果消息中间件在等待确认应答超时之后就会重新投递,直到下游消费者返回消费成功响应为止。
一般消息中间件可以设置消息重试的次数和时间间隔,如果最终还是不能成功投递,则需要手工干预。这里之所以使用人工干预,而不是使用让A系统回滚,主要是考虑到整个系统设计的复杂度问题。

基于可靠消息服务的分布式事务,前半部分使用异步,注重性能;后半部分使用同步,注重开发成本。

最大努力通知


最大努力通知也被称为定期校对,其实是对第二种解决方案的进一步优化。它引入了本地消息表来记录错误消息,然后加入失败消息的定期校对功能,来进一步保证消息会被下游系统消费。

第一步: 消息由系统A投递到中间件

处理业务的同一事务中,向本地消息表中写入一条记录

准备专门的消息发送者不断地发送本地消息表中的消息到消息中间件,如果发送失败则重试

第二步: 消息由中间件投递到系统B

消息中间件收到消息后负责将该消息同步投递给相应的下游系统,并触发下游系统的任务执行

当下游系统处理成功后,向消息中间件反馈确认应答,消息中间件便可以将该条消息删除,从而该事务完成

对于投递失败的消息,利用重试机制进行重试,对于重试失败的,写入错误消息表

消息中间件需要提供失败消息的查询接口,下游系统会定期查询失败消息,并将其消费

这种方式的优缺点:

优点:  一种非常经典的实现,实现了最终一致性。

缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

TCC事务


TCC即为Try Confirm Cancel,它属于补偿型分布式事务。TCC实现分布式事务一共有三个步骤:

Try:尝试待执行的业务 这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执行所需的全部资源

Confirm:确认执行业务 确认执行业务操作,不做任何业务检查, 只使用Try阶段预留的业务资源。
通常情况下,采用TCC则认为 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需引入重试机制或人工处理。

Cancel:取消待执行的业务 取消Try阶段预留的业务资源。
通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理。

TCC两阶段提交与XA两阶段提交的区别是:

XA是资源层面的分布式事务,强一致性,在两阶段提交的整个过程中,一直会持有资源的锁。

TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。

TCC事务的优缺点:

优点: 

把数据库层的二阶段提交上提到了应用层来实现,规避了数据库层的2PC性能低下问题。

缺点: 

TCC的Try、Confirm和Cancel操作功能需业务提供,开发成本高。

SAGA


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

补偿协议:在Saga模式下,分布式事务内有多个参与者,每个参与者都是正向补偿服务。上图中的T1~Tn就是正向调用,C1~Cn是补偿调用,正向调用和补偿调用是一一对应的关系。

假设有n个被调用方服务,T1就是对服务一的调用,接着T2是对服务方二的调用,T3是对服务方三的调用。如果这个时候返回了失败,那么就需要进行回滚,此时就会调用T2的对应补偿C2,调用T1的对应补偿C1,使得分布式事务回到初始状态。

Saga 正向服务与补偿服务都需要业务开发者实现,因此是业务入侵的。Saga 模式下分布式事务通常是由事件驱动的,各个参与者之间是异步执行的,Saga 模式是一种长事务解决方案。

Saga 模式使用场景

Saga 模式适用于业务流程长且需要保证事务最终一致性的业务系统,Saga 模式一阶段就会提交本地事务,无锁、长流程情况下可以保证性能。

事务参与者可能是其它公司的服务或者是遗留系统的服务,无法进行改造和提供 TCC 要求的接口,可以使用 Saga 模式。

Saga模式的优势与缺点

优势:

一阶段提交本地数据库事务,无锁,高性能;

参与者可以采用事务驱动异步执行,高吞吐 补偿服务即正向服务的“反向”,易于理解,易于实现;

缺点:

Saga 模式由于一阶段已经提交本地数据库事务,且没有进行“预留”动作,所以不能保证隔离性。

SEATA


2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit AndRollback),其愿景是让分布式事务的使用像本地事务的使用一样,简单和高效,并逐步解决开发者们遇到的分布式事务方面的所有难题。后来更名为 Seata,意为:Simple Extensible AutonomousTransaction Architecture,是一套分布式事务解决方案。

Seata的设计目标是对业务无侵入,因此从业务无侵入的2PC方案着手,在传统2PC的基础上演进。它把一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的本地事务。

Seata主要由三个重要组件组成:

TC:Transaction Coordinator 事务协调器,管理全局的分支事务的状态,用于全局性事务的提交和回滚。

TM:Transaction Manager 事务管理器,用于开启、提交或者回滚全局事务。

RM:Resource Manager 资源管理器,用于分支事务上的资源管理,向TC注册分支事务,上报分支事务的状态,接受TC的命令来提交或者回滚分支事务。

Seata的执行流程如下:

A服务的TM向TC申请开启一个全局事务,TC就会创建一个全局事务并返回一个唯一的XID

A服务的RM向TC注册分支事务,并及其纳入XID对应全局事务的管辖

A服务执行分支事务,向数据库做操作

A服务开始远程调用B服务,此时XID会在微服务的调用链上传播

B服务的RM向TC注册分支事务,并将其纳入XID对应的全局事务的管辖

B服务执行分支事务,向数据库做操作

全局事务调用链处理完毕,TM根据有无异常向TC发起全局事务的提交或者回滚

TC协调其管辖之下的所有分支事务, 决定是否回滚

Seata实现2PC与传统2PC的差别:

架构层次方面,传统2PC方案的 RM 实际上是在数据库层,RM本质上就是数据库自身,通过XA协议实现,而 Seata的RM是以jar包的形式作为中间件层部署在应用程序这一侧的。

两阶段提交方面,传统2PC无论第二阶段的决议是commit还是rollback,事务性资源的锁都要保持到Phase2完成才释放。而Seata的做法是在Phase1 就将本地事务提交,这样就可以省去Phase2持锁的时间,整体提高效率。

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

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

相关文章

【越早知道越好】的道理——能够大大提升效率的【快捷键】

文章目录 1️⃣虚拟桌面第一步:打开任务视图第二步:创建桌面第三步:桌面切换第四步:桌面删除 2️⃣窗口切换3️⃣桌面分屏如何分屏 前言🧑‍🎤:作为程序员👨‍💻&#xf…

scratch足球射门练习 中国电子学会图形化编程 少儿编程 scratch编程等级考试一级真题和答案解析2023年3月

目录 scratch足球射门练习 一、题目要求 1、准备工作 2、功能实现 二、案例分析

基于Java+SpringBoot+Vue前后端分离仓库管理系统设计实现

基于JavaSpringBootVue前后端分离仓库管理系统设计实现 博主介绍:5年java开发经验,专注Java开发、定制、远程、指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系方式…

RocketMQ 5.0 时代,6 张图带你理解 Proxy!

大家好,我是君哥。今天来聊一聊 RocketMQ 5.0 中的 Proxy。 RocketMQ 5.0 为了更好地拥抱云原生,引入了无状态的 Proxy 模块,新的架构图如下: 引入 Proxy 模块后,Proxy 承担了协议适配、权限管理、消息管理等计算功能…

JVM垃圾回收GC 详解(java1.8)

目录 垃圾判断算法(你是不是垃圾?) 引用计数法 可达性算法 对象的引用 强引用 软引用 弱引用 虚引用 对象的自我救赎 垃圾回收算法--分代 标记清除算法 复制算法 标记整理法 垃圾处理器 垃圾判断算法(你是不是垃圾&…

Anaconda+PyTorch环境搭建

AnacondaPyTorch环境搭建 环境Anaconda安装配置下载镜像 cuda和cudnncudacudnn pytorch参考文章 环境 win10 22hx nvidia driver 528.89 Anaconda安装 在清华镜像中选择合适的版本及对应系统 https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/ 下载好之后一路next即可…

vscode笔记

vscode怎么中止运行 控制台—输出,结束运行: 控制台右击,然后点击Stop Code Run或者CtrlAltM快捷键 停止正在运行的Python脚本 在VS Code的右下角,选择正在运行的终端, 点右键,终止终端 VS code怎么终止…

简单的小型C++项目怎么用CMAKE进行管理

项目目录: 根目录下共有两个文件夹,分别为include、src,有两个文件,分别为CMakeLists.txt和main.cpp main函数 可以看出,include了func.h,且func.h的声明在include文件夹下,定义在src文件夹下的…

全网唯一!Matlab世界顶尖艺术品配色包Rmetbrewer

想要绘制一幅颜色搭配合理、好看又不花哨的论文插图,该如何操作呢? 正所谓求其上者得其中,求其中者得其下。 那么,向高手借鉴思路,无疑是一种不落下乘的好策略。 而在色彩搭配领域,像莫奈、梵高这些世界…

WPS表格数据出现绿色小三角,单引号,E+的原因说明和完美解决方案,终结版。

复盘问题的原因,了解原因的原因,预测事件的结果,推测结果产生的结果。 问题描述:好好的数据,复制进wps,左上角就会出现绿色三角。怎么去掉呢? 迷惑问题2:点击之后,绿色三…

代码优化- 前端优化

常量折叠 基本思想:在编译期间计算表达式的值(编译时静态计算) 例如:a 3 5 > a 8,if (true && false) ... > if (false) 好处是:语法树的节点数量减少了,意味着编译器要维护…

STM32—0.96寸OLED液晶显示

本文主要介绍基于STM32F103的0.96寸的OLED液晶显示,详细关于0.96寸OLED液晶屏幕的介绍可参考这篇博客:https://blog.csdn.net/u011816009/article/details/130119426 一、简介 OLED被称为有机激光二极管,也被称为有机激光显示,O…

学生宿舍管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设!!! 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址:https://download.csdn.net/download/qq_50954361/87700423 更多系统资源库…

Sprinboot聚合项目归荑

1、前言 在创建springboot项目时,都会有一个Main方法。如果将Springboot项目设计成聚合项目时,我们是不是要把所有的子项目都按照Springboot的方式创建呢?如果是会出现什么问题,以及我们怎么解决呢? 如果我们使用maven…

ChatGPT原理详解+实操

言 ChatGPT已近火了快大半年了,从去年刚出来的时候小编就关注了一下,也具体的使用过,然后就惊为天人,再然后就没有然后了,因为小编那段时间沉迷于AIGC了。ChatGPT今年开年后更是火的一塌糊涂,无论是行业内…

chatgpt智能提效职场办公-ppt怎么加音乐背景

作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 在 PowerPoint 中,您可以轻松地将音乐作为背景音乐添加到您的演示文稿中。下面是步骤: 打开您的 PowerPoint 演…

【大厂直通车】哔哩哔哩日常实习_测开面经

📑哈喽,大家好,我是小浪;本篇博客更新的是最新B站测开面经,本专栏非常适合目前准备找实习,或者准备冲秋招测试,测开方向的同学阅读订阅,持续更新各大厂真题面经,带你成为offer收割机!! 🧃对于订阅本专栏的同学们,博主在努力更新,只需要一杯奶茶钱,订阅本专栏,…

【命名空间】using namespace std是什么意思?

目录 一、前言二、命名空间2.1命名空间的定义2.2命名空间的成员调用2.2.1加命名空间名称及作用域限定符2.2.2使用using将命名空间中某个成员引入2.2.3使用using namespace 命名空间名称 引入 2.3命名空间的成员的优先级 三、using namespace std 一、前言 我们很多接触过C编程…

考了华为认证,如何找工作?能进哪些公司?有没有前景?

哪些人适合考华为?考了华为认证好不好找工作?这应该是困扰很多网工的问题。 俗话说,男怕入错行,女怕嫁错郎。如何选择一条适合自己的道路,提前做好职业规划,对个人职业发展至关重要。 下面就为大家整理了…

C#基础学习--预处理指令

目录 什么是预处理指令 基本规则 #define 和 #undef 指令 条件编译 条件编译结构 诊断指令 行号指令 ​编辑 区域指令 #pragam warning 指令 什么是预处理指令 源代码指定了程序的定义,预处理指令指示编译器如何处理源代码 基本规则 #define 和 #undef 指令…