【Redis-11】Redis事务实现原理

news2025/2/2 16:38:08

 Redis通过MULTI、EXEC、WATCH等命令来实现事务的功能,事务提供了一种将多个命令请求打包,然后一次性,顺序性的执行多个命令的机制。在事务执行期间,服务器不会中断事务去执行其他客户端的命令,他会讲事务中所有命令执行完成后,才会去处理其他客户端的命令请求。

1. 事务的实现

 一个事务从开始到结束通常会经历三个阶段:事务开始、命令入队、事务执行。接下来我们就针对这三个阶段看一下事务的整个执行过程。

  • 事务开始:Redis事务的开始是通过MULTI这个命令开始的,此命令就标志着客户端从非事务的状态切换到事务的状态,具体表现在客户端状态标记的打开,即:client.flags |= REDIS_MULTI
  • 命令入队:当客户端处于事务状态时,服务器除了会执行EXEC、DISCARD、WATCH、MULTI命令之外,其余的命令都会放在一个事务队列中,然后向客户端返回QUEUED
  • 事务队列:每个客户端都有自己的事务状态,保存在client.mstate属性中,事务状态属性包含一个事务队列,以及一个入队的命令计数器(事务队列的长度),事务队列以先进先出的方式保存入队命令。
typedef struct client {
    ...
    // 客户端的事务状态
    multiState mstate;      /* MULTI/EXEC state */
    ...
} client;
typedef struct multiState {
	// 队列,保存客户端命令
    multiCmd *commands;     /* Array of MULTI commands */
    // 入队命令的个数
    int count;              /* Total number of MULTI commands */
    ...
} multiState;
  • 执行事务:当客户端发送EXEC命令时,服务器会遍历客户端的事务队列,一次性不间断的执行完队列中所有的命令,并将结果返回给客户端。

2. WATCH命令的实现

WATCH命令是一个乐观锁,可以在执行EXEC命令之前,监视任意数量的数据库键值对,并且在 EXEC命令执行时,检查监视的键是否有修改过,如果是,服务器会拒绝执行,并向客户端返回事务执行失败的回复。
 首先看一下WATCH命令的实现原理:在代表数据库的结构redisDB中,保存着代表被WATCH监视的数据库键,这个属性是dict,字典的键是被监视的键,字典的值是一个链表,链表每个节点是WATCH对应键值对的客户端。

typedef struct redisDb {
	// 代表WATCH监视的键值对及对应客户端
    dict *watched_keys;         /* WATCHED keys for MULTI/EXEC CAS */
	...
} redisDb;

 所以通过这个字典,其实可以知道哪些客户端在监听哪些数据库的键值。比如有这么一个场景,客户端c1、c2执行了WATCH name,客户端c3执行了WATCH age,客户端c4、c5、c6执行了WATCH gender,通过一个图示可以展现如下:
在这里插入图片描述
 当数据库执行键值对的写操作时,会对watched_keys进行检查,查看是否有客户端正在监视对应的key。如果有的话,会调用相关函数,对所有的客户端进行标志的修改:client.flags |= REDIS_DIRTY_CAS,表示该客户端的事务安全性已经遭到了破坏。
 当服务器接收到EXEC命令准备执行时,会检查client.flags是否打开了REDIS_DIRTY_CAS的标识。如果标识被打开,说明事务已经不再安全,服务器拒绝执行,否则服务器会正常执行客户端的事务。

3. 事务的ACID特性

 这里是要去对比关系型数据库原子性、一致性、隔离性、持久性的四个特性。

  • 原子性: 原子性指的是,数据库会将事务中的多个操作当成一个整体来执行,要么执行全部操作,要么一个也不执行。Redis事务与传统关系型数据库原子性区别在于,首先Redis事务不支持回滚,其次Redis只会在命令书写错误或者格式错误的时候会拒绝执行事务,而在命令执行期间的错误(比如参数类型错误等),redis会跳过继续执行余下的所有命令。
  • 一致性: 一致性指的是数据库在执行事务之前和之后的状态应该是一直的,无论事务是否执行成功,这里的一致性指的符合数据库本身的定义和要求,不包含非法字符或者无效的错误数据。这一点体现在,redis无论是通过检查命令的合法性而拒绝执行事务,或者事务执行期间命令参数错误也继续余下命令时,都不会被数据库做出任何错误的修改,所以符合一致性。
  • 隔离性: 隔离性是指即使数据库中有多个事务并发的执行,各个事务之间也不会互相影响,并且在并发状态下执行的事务和串行状态下执行事务的结果完全相同。因为Redis使用单线程的方式来执行事务,并且服务器在执行事务期间不会对事务中断,所以Redis这种串行的方式可以保证事务的隔离性。
  • **持久性:**持久性是指,当事务执行完成时,事务的结果已经被永久性的保存到储存介质中,即使服务器发生故障,也不会导致事务失效。Redis事务执行时,会依次执行队列中的所有命令,所以事务持久性与服务器配置的持久化方式有关,如果配置了RDB或者AOF的持久化,且命令执行后被持久化到磁盘,也是具备持久的特性。

 综上,就是事务执行的部分场景,如有问题,可以给我留言。

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

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

相关文章

谈主成分分析/因子分析中的特征值“矩阵近似”

主成分分析和因子分析是数据降维的常用手段,其中以特征值为载体,在不断降维“近似”原本的协方差矩阵。 CSDN中一些文章在介绍这个问题或者叫“特征值分解”时,讲得都比较学术化,今天用一个小例子,还是面向新人&#…

Redis高可用之哨兵机制实现细节

Redis高可用之哨兵机制实现细节 本文来自我的 technotes [1] Redis篇,欢迎你常来逛逛。 正文 在上一篇的文章《Redis高可用全景一览》中,我们学习了 Redis 的高可用性。高可用性有两方面含义:一是服务少中断,二是数据少丢失。主…

【树莓派不吃灰】兄弟连篇⑥ Linux系统进程管理

目录1、进程查看1.1 ps1.2 top1.3 pstree2、终止进程2.1 kill2.2 killall2.3 pkill3、工作管理4、系统资源查看4.1 vmstat 监控系统资源4.2 dmesg 开机内核检测信息4.3 free 查看内存使用4.4 查看cpu信息4.5 uptime4.6 uname4.7 判断当前系统位数4.8 查询当前linux发行版本4.9 …

Windows及Kail安装配置

apache在kali环境搭建 Kali虚拟机中是包含有Apache的,在/etc目录下ls即可显示出来, 所以这里只需要进行配置就可以了。 图1.1 Apache2目录 打开Apache服务,开启后可以使用status命令查看服务状态。 /etc/init.d/apache2 start /etc/init.d…

【5】控制语句

指针 Go中不用“->”运算符,用的是 “.” 选择符“&”:取地址符“*”:访问目标对象符默认值为:nil (不是NULL)、- -:作为语句,只可以自己放一行,而且放在右边(不是表达式) …

一款强大的API接口文档管理工具(Smart-Doc + Torna)

【本文由龙飞同学供稿】 在团队协作开发项目的时候,接口文档承担着向其他开发人员说明接口相关信息的重要任务,因此,一份清晰而又相近的接口文档至关重要。 但是,写接口文档的痛苦想必各位开发人员都体验过,明明写接…

在职读研有意义么?来社科院与杜兰大学金融管理硕士项目探寻答案

在职场当我们遇到变化,尤其是发展上有瓶颈期的时候,我们会寻找向内突破,通过提升自己的核心竞争力来应对,通过再学习来增加自身的优势。那么在职读研有意义吗?我们来社科院与杜兰大学金融管理硕士项目来探寻。 一、读在…

Postman接口测试之Mock快速入门

一、Mock简介 1.Mock定义 Mock是一种比较特殊的测试技巧,可以在没有依赖项的情况下进行接口或单元测试。通常情况下,Mock与其他方法的区别是,用于模拟代码依赖对象,并允许设置对应的期望值。简单一点来讲,就是Mock创建…

【专业数据】八.2020~2022年北京交通大学【人工智能】专业复试线/分数线差/计划招生数/复试数/录取数/复试比例/录取率

文章目录 1.专业介绍2.2020-2022年国家线/复试线/分数线差2.1.数据总览2.2.数据指标2.2.1.复试分数线2.2.2.分数线差3.2020-2022年计划招生数/复试数/录取数/复试比例/录取率3.1.数据总览3.2.数据指标3.2.1.复试比例3.2.2.录取率4.参考资料欢迎订阅本专栏:《北交计算机复试经验…

python+appium(4)

conftest进阶使用 思路:我们平时导包多,而且经常使用某一段代码,一般我们使用封装的思想进行优化,pytest中conftest模块提供了更高效的方法 你可以添加任何想一次性封装的代码,这里吧代码变成变量,需要使…

Android APP 自动化测试搭建:Appium + Genymotion + [Robot Framework] Open Application

Android APP 自动化测试搭建: Appium Genymotion [Robot Framework] Open Application1. 安装 Android SDK2. 安装 ADB(Android Debug Bridge)3. 配置 platform-tools 目录(1) 复制 adb 等工具(2) 添加 apksigner.jar4. 配置 Appium Server…

C语言—函数

函数&#xff1a;将代码块封装成一个个不同的函数&#xff0c;在使用时可以多次的调用&#xff0c;不需要关心内部的实现&#xff1b; #include <stdio.h>void MyPrint() {printf("&&&&&&&&&&&\n");printf("…

BaseDet: 走过开发的弯路

BaseDet 开源啦&#xff01;该 repo 提供了一些经典的检测 SOTA 模型以及相关组件&#xff0c;欢迎大家按需取用~~GitHub&#xff1a;https://github.com/megvii-research/basedetMegStudio 使用示例&#xff1a;https://studio.brainpp.com/project/28826?nameBaseDet%E4%BD%…

重磅!TDengine 3.2.0 正式发布

近日&#xff0c;TDengine 3.0.2.0 正式发布了。这是自今年 8 月份 TDengine 3.0 发布以来的第一个重要改进版本。 TDengine 3.0 带来了几大核心特性&#xff0c;包括云原生架构、流式计算&#xff0c;还增强了数据订阅功能&#xff1b;更重要的是&#xff0c;3.0 系列版本开始…

Python是个什么鬼?为什么那么多人都要学它?真的有这么牛吗?

为什么那么多人选择学习python&#xff1f; Python在人工智能、大数据、自动化运维、全栈开发等方面具有独特的优势。随着Python继续占据编程语言主流的趋势&#xff0c;全国各城市的招聘岗位和薪酬将大幅增加。此外&#xff0c;随着人工智能在中国的投资和规划&#xff0c;对…

C++ Primer 第三章 Strings, Vectors, and Arrays

C Primer 第三章 Strings, Vectors, and Arrays3.1. Namespace using Declarations3.2. Library string Type3.2.1. Defining and Initializing stringsDirect and Copy Forms of Initialization3.2.2. Operations on stringsReading and Writing stringsUsing getline to Read…

【图像处理】opencv | 形态学运算:腐蚀,膨胀,开运算,闭运算| 二值图像处理

文章目录前言一、腐蚀和膨胀1.1腐蚀1.2膨胀二、开运算与闭运算三、礼帽与黑帽前言 参考视频&#xff1a;opencv教学 参考教材&#xff1a;《数字图像处理基础》 我的代码基本是跟着B站的视频里面敲了一遍&#xff0c;然后结合教材对指定区域做了一些加强学习 一、腐蚀和膨胀 …

华为云APIArts:API全生命周期一体化解决方案,帮助您端到端呵护您的API

摘要&#xff1a;华为云API Arts是API设计、API开发、API测试、API托管、API运维、API变现一体化协作平台&#xff0c;通过维护API各开发阶段数据高度一致&#xff0c;支持开发者高效实现API全流程一站式体验。 伴随数字化浪潮的到来&#xff0c;应用编程接口(API)已经成为一个…

【MySQL】2.MySQL库操作

文章目录1.0 MySQL基本使用1.1 理解数据库操作2.0 MySQL数据库操作详解2.1创建数据库2.2 字符集和校验规则2.2修改数据库2.3删除数据库2.4查看数据库链接1.0 MySQL基本使用 1.1 理解数据库操作 查看数据库配置文件 指令: vim /etc/my.cnf 登录数据库 指令&#xff1a; mysql…

[第十三届蓝桥杯/java/算法]A——排列字母

&#x1f9d1;‍&#x1f393;个人介绍&#xff1a;大二软件生&#xff0c;现学JAVA、Linux、MySQL、算法 &#x1f4bb;博客主页&#xff1a;渡过晚枫渡过晚枫 &#x1f453;系列专栏&#xff1a;[编程神域 C语言]&#xff0c;[java/初学者]&#xff0c;[蓝桥杯] &#x1f4d6…