Redis 实战之事务的实现

事务的实现

  • 事务开始
  • 命令入队
  • 事务队列
  • 执行事务
  • 总结

一个事务从开始到结束通常会经历以下三个阶段:

1、 事务开始;
2、 命令入队;
3、事务执行。

本节接下来的内容将对这三个阶段进行介绍, 说明一个事务从开始到结束的整个过程。

事务开始

MULTI 命令的执行标志着事务的开始:

redis> MULTI
OK

MULTI 命令可以将执行该命令的客户端从非事务状态切换至事务状态, 这一切换是通过在客户端状态的 flags 属性中打开 REDIS_MULTI 标识来完成的, MULTI 命令的实现可以用以下伪代码来表示:

def MULTI():# 打开事务标识client.flags |= REDIS_MULTI# 返回 OK 回复replyOK()

命令入队

当一个客户端处于非事务状态时, 这个客户端发送的命令会立即被服务器执行:

redis> SET "name" "Practical Common Lisp"
OKredis> GET "name"
"Practical Common Lisp"redis> SET "author" "Peter Seibel"
OKredis> GET "author"
"Peter Seibel"

与此不同的是, 当一个客户端切换到事务状态之后, 服务器会根据这个客户端发来的不同命令执行不同的操作:

如果客户端发送的命令为 EXECDISCARDWATCHMULTI 四个命令的其中一个, 那么服务器立即执行这个命令。
与此相反, 如果客户端发送的命令是 EXECDISCARDWATCHMULTI 四个命令以外的其他命令, 那么服务器并不立即执行这个命令, 而是将这个命令放入一个事务队列里面, 然后向客户端返回 QUEUED 回复。

服务器判断命令是该入队还是该立即执行的过程可以用流程图 IMAGE_ENQUEUE_OR_EXEC 来描述。
在这里插入图片描述

事务队列

每个Redis 客户端都有自己的事务状态, 这个事务状态保存在客户端状态的 mstate 属性里面:

typedef struct redisClient {// ...// 事务状态multiState mstate;      /* MULTI/EXEC state */// ...} redisClient;

事务状态包含一个事务队列, 以及一个已入队命令的计数器 (也可以说是事务队列的长度):

typedef struct multiState {// 事务队列,FIFO 顺序multiCmd *commands;// 已入队命令计数int count;} multiState;

事务队列是一个 multiCmd 类型的数组, 数组中的每个 multiCmd 结构都保存了一个已入队命令的相关信息, 包括指向命令实现函数的指针, 命令的参数, 以及参数的数量:

typedef struct multiCmd {// 参数robj **argv;// 参数数量int argc;// 命令指针struct redisCommand *cmd;} multiCmd;

事务队列以先进先出(FIFO)的方式保存入队的命令: 较先入队的命令会被放到数组的前面, 而较后入队的命令则会被放到数组的后面。

举个例子, 如果客户端执行以下命令:

redis> MULTI
OKredis> SET "name" "Practical Common Lisp"
QUEUEDredis> GET "name"
QUEUEDredis> SET "author" "Peter Seibel"
QUEUEDredis> GET "author"
QUEUED

那么服务器将为客户端创建图 IMAGE_TRANSACTION_STATE 所示的事务状态:

最先入队的 SET 命令被放在了事务队列的索引 0 位置上。
第二入队的 GET 命令被放在了事务队列的索引 1 位置上。
第三入队的另一个 SET 命令被放在了事务队列的索引 2 位置上。
最后入队的另一个 GET 命令被放在了事务队列的索引 3 位置上。

在这里插入图片描述

执行事务

当一个处于事务状态的客户端向服务器发送 EXEC 命令时, 这个 EXEC 命令将立即被服务器执行: 服务器会遍历这个客户端的事务队列, 执行队列中保存的所有命令, 最后将执行命令所得的结果全部返回给客户端。

举个例子, 对于图 IMAGE_TRANSACTION_STATE 所示的事务队列来说, 服务器首先会执行命令:

SET "name" "Practical Common Lisp"

接着执行命令:

GET "name"

之后执行命令:

SET "author" "Peter Seibel"

再之后执行命令:

GET "author"

最后,服务器会将执行这四个命令所得的回复返回给客户端:

redis> EXEC
1) OK
2) "Practical Common Lisp"
3) OK
4) "Peter Seibel"

EXEC 命令的实现原理可以用以下伪代码来描述:

def EXEC():# 创建空白的回复队列reply_queue = []# 遍历事务队列中的每个项# 读取命令的参数,参数的个数,以及要执行的命令for argv, argc, cmd in client.mstate.commands:# 执行命令,并取得命令的返回值reply = execute_command(cmd, argv, argc)# 将返回值追加到回复队列末尾reply_queue.append(reply)# 移除 REDIS_MULTI 标识,让客户端回到非事务状态client.flags &= ~REDIS_MULTI# 清空客户端的事务状态,包括:# 1)清零入队命令计数器# 2)释放事务队列client.mstate.count = 0release_transaction_queue(client.mstate.commands)# 将事务的执行结果返回给客户端send_reply_to_client(client, reply_queue)

总结

事务提供了一种将多个命令打包, 然后一次性、有序地执行的机制。
多个命令会被入队到事务队列中, 然后按先进先出(FIFO)的顺序执行。
事务在执行过程中不会被中断, 当事务队列中的所有命令都被执行完毕之后, 事务才会结束。
带有 WATCH 命令的事务会将客户端和被监视的键在数据库的 watched_keys 字典中进行关联, 当键被修改时, 程序会将所有监视被修改键的客户端的 REDIS_DIRTY_CAS 标志打开。
只有在客户端的 REDIS_DIRTY_CAS 标志未被打开时, 服务器才会执行客户端提交的事务, 否则的话, 服务器将拒绝执行客户端提交的事务。
Redis 的事务总是保证 ACID 中的原子性、一致性和隔离性, 当服务器运行在 AOF 持久化模式下, 并且 appendfsync 选项的值为always 时, 事务也具有耐久性

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

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

相关文章

ICLR 2024 杰出论文出炉:“大模型”成最大赢家

昨天,国际表征学习大会(International Conference on Learning Representations,ICLR)公布了 ICLR 2024 杰出论文。 其中,在 5 篇杰出论文中,有 4 篇论文涉及大模型。另外,也有 11 篇论文获得荣…

Linux学习之高级IO

之前的内容我们基本掌握了基础IO,如套接字,文件描述符,重定向,缓冲区等知识都是文的基本认识,而高级IO则是指更加高效的IO。 对于应用层,在读写的时候,本质就是把数据写给OS,若一方…

从互联网医院源码到搭建:开发视频问诊小程序的技术解析

如今,视频问诊小程序作为医疗服务的一种新形式,正逐渐受到人们的关注和青睐。今天,小编将为您详解视频问诊小程序的开发流程。 一、背景介绍 互联网医院源码是视频问诊小程序开发的基础,它提供了一套完整的医疗服务系统框架&…

zlib编译后静态库调用时遇到的无法解析的外部符号问题

编译zlib的静态库后引用到项目中使用,发现报下面的链接错误: error LNK2019: 无法解析的外部符号 _zlibVersion error LNK2019: 无法解析的外部符号 _deflateEnd error LNK2019: 无法解析的外部符号 _deflate error LNK2019: 无法解析的外部符号 _deflat…

【Linux 性能详解】CPU性能篇

目录 平均负载(Load Average) CPU上下文切换 进程上下文切换 线程上下文切换 中断上下文切换 中断 硬中断 软中断 CPU使用率 性能分析工具 平均负载(Load Average) 平均负载?这个词对很多人来说&#xff0c…

构建第一个ArkTS应用之@AppStorage:应用全局的UI状态存储

AppStorage是应用全局的UI状态存储,是和应用的进程绑定的,由UI框架在应用程序启动时创建,为应用程序UI状态属性提供中央存储。 和AppStorage不同的是,LocalStorage是页面级的,通常应用于页面内的数据共享。而AppStora…

中国护照照片尺寸分辨率要求及居家自拍制作教程

经常出国的小伙伴都知道,护照照片作为出国旅行的重要身份证明文件,其规格和质量要求非常严格。本文将详细介绍中国护照照片的具体要求,并提供一些实用的居家自拍技巧,帮助您轻松拍出符合规定的护照照片(手机和相机居家…

革新品质检测,质构科技重塑肉类行业新篇章

革新品质检测,质构科技重塑肉类行业新篇章 在现代社会,消费者对食品安全和品质的要求日益提升,特别是在肉类行业。为了满足这一市场需求,质构科技凭借其精准、高效的优势,正逐渐成为肉类品质检测的新星。今天&#xf…

QT-TCP通信

网上的资料太过于书面化,所以看起来有的让人云里雾里,看不懂C-tcpsockt和S-tcpsocket的关系 所以我稍微画了一下草图帮助大家理解两个套接字之间的关系。字迹有的飘逸勉强看看 下面是代码 服务端: MainWindow::MainWindow(QWidget *parent) …

windows10打印机共享完美解决方案

提到文件共享大家并不陌生,相关的还有打印机共享,这个多见于单位、复印部,在一个区域网里多台电脑共用一台打印机,打印资料非常方便,就包括在家里,我们现在一般都会有多台电脑或设备,通过家庭网络联接,如果共享一台打印机的话也是件便捷的事。 但是随着操作系统的更新…

web前端框架设计第八课-表单控件绑定

web前端框架设计第八课-表单控件绑定 一.预习笔记 1.v-model实现表单数据双向绑定 2.搜索数据的实现 3.全选案例实现1—JQ方法 4.单选案例实现 二.课堂笔记 三.课后回顾 –行动是治愈恐惧的良药,犹豫拖延将不断滋养恐惧

如何阅读:一个已被证实的低投入高回报的学习方法的笔记

系列文章目录 如何有效阅读一本书笔记 如何阅读:一个已被证实的低投入高回报的学习方法 麦肯锡精英高效阅读法笔记 读懂一本书笔记 文章目录 系列文章目录第一章 扫清阅读障碍破解读不快、读不进去的谜题一切为了阅读小学教师让你做,但中学老师阻止你做的…

快速搭建webase-front并且部署合约

PS: 因为我开发时候要用到fisco和webase-front,避免官方文档粘贴, 因此直接整理下面的笔记。开发的时候,好粘贴。1.搭建4节点联盟链 前提 curl 一种命令行工具 apt install -y openssl curl创建操作目录, 下载安装脚本 cd ~ && mkdir -p fisco && cd fisco…

【京东电商API接口】 | 京东某商品销量数据分析可视化

Python当打之年 当打之年,专注于各领域Python技术,量的积累,质的飞跃。后台回复:【可视化项目源码】可获取可视化系列文章源码和数据 本期将利用Python分析「京东商品数据接口」,希望对大家有所帮助,如有疑…

Quartz怎么简单创建一个定时执行的任务

1.安装Quartz包 2.编写Job任务 继承 IJob编辑自定义任务 3.调用job,以指定时间策略执行 定时600s执行一次 StdSchedulerFactory factory new StdSchedulerFactory(); IScheduler scheduler await factory.GetScheduler(); await scheduler.Start();// 定义…

带你快速掌握Spring Task

Spring Task ⭐Spring Task 是Spirng框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑 📌一款定时任务框架 应用场景 信用卡信息银行贷款信息火车票信息 只要是需要定时处理的场景都可以使用Spring Task 只要有定时,就会有…

用js代码实现贪吃蛇小游戏

js已经学了大部分了,现在就利用我所学的js知识试试做贪吃蛇小游戏吧 以下部分相关图片以及思路笔记均出自渡一陈老师的视频 首先制作简单的静态页面,添加贪吃蛇移动的背景和相关图片,比如开始游戏等等 将各个功能均封装在函数中&#xff0…

react【实用教程】 搭建开发环境(2024版)Vite+React (官方推荐)

以项目名 reactDemo为例 1. 下载脚手架 在目标文件夹中打开命令行 npm create vite2. 安装项目依赖 cd reactDemo npm i若安装失败,则修改下载源重试 npm config set registry https://registry.npmmirror.com3. 启动项目 npm run dev4. 预览项目 浏览器访问 http…

iPhone 数据恢复软件 – 恢复丢失的 iPhone 数据

恢复丢失的 iPhone 数据,奇客数据恢复iPhone版。如今的 iPhone 用户在他们的设备上存储了大量数据,从照片和与亲人的文本对话到商业和医疗信息。其中一些是保密的;其中大部分内容都是非常个人化的;而且大多数一旦丢失就无法替代。…

vmware虚拟机内删除文件后宿主机空间不释放

问题描述 linux下,vmware内虚拟机删除文件,宿主机空间不释放,D盘快满了 解决方法 通过vmware-toolbox进行空间回收 安装 在虚拟机内操作 yum install -y open-vm-tools 清理 在虚拟机内操作 #查看磁盘的挂载点 sudo /usr/bin/vmware…