【Redis进阶】事务

news2024/12/24 8:53:18

1. Redis与MySQL的事务差别

相信一谈到事务,大家马上就能联想到MySQL的事务,其事务具有ACID四大特性,但是Redis的事务相比较于MySQL,那就是个"弟中弟",下面我们就来简单对比两者的事务特性:

  • 原子性:关于Redis事务是否具备"原子性"是存在争议的,Redis的原子性最原始的含义就是指"把一组操作打包在一起执行,要么全都执行;要么全都不执行"(但是Redis并没有回滚操作,即若中间有操作执行失败,Redis也会继续执行下去),但是对于MySQL来说,其提供的"原子性"特性保证这组操作要么全都执行成功,要么全都不执行(即MySQL事务带有回滚机制)
  • 一致性:Redis的事务不存在一致性,因为没有提供回滚机制,因此若中间操作执行失败,就可能存在数据不一致的情况
  • 持久性:Redis中的事务不存在持久性,尽管Redis含有持久化机制,但是这与事务特性无关
  • 隔离性:Redis中的事务不涉及到隔离性,因为Redis是一个单线程的服务器模型,所有的请求/事务都是串行执行的

2. Redis事务概述

目的:Redis中的事务最根本的目的就是将一组操作打包在一起执行,中间不允许有别的客户端插队执行
举一个形象生动的例子,我和我的朋友一起去吃烧烤,我一开始点了一堆五花肉、羊肉、牛肉、猪肉等菜品,但是我的朋友还没到,于是我让老板先存单不着急烤,当我的朋友到了以后他又点了一堆猪腰子、生蚝等菜品。此时我们告诉老板可以烤了(在这里我们前后两堆菜品一定是需要放在一起烤的,不会出现我们的菜品跟别的客人放一起端上来的情况)
实现方式:Redis服务器为每个客户端维护了一个队列(先进先出),当"事务开启"之后,客户端发送的命令就会加入到服务端对应的队列上而不是立即执行,如果遇到相应客户端的"执行事务"命令则按顺序将队列中的操作进行执行,并且根据原子性,只有处理完一个客户端的队列操作后才能执行下一个客户端的事务

💡 思考一下:为什么Redis中的事务如此简单,不设计的跟MySQL一样强大呢?

  1. 在空间上,需要额外的空间存储相应的更新操作(如undolog、redolog等等)
  2. 在时间上,回滚操作也需要额外的执行性能开销

而我们Redis是基于内存的数据库,追求性能!

应用场景:我们用到Redis中的事务操作往往在一些需要将一组操作放在一起执行的场景中,比如说秒杀场景中,提供下列伪代码,如果不加以任何限制让多个客户端并发执行,就可能存在超卖的问题!在Redis中我们就可以通过事务的方式来解决这种问题!

get count;
if (count > 0) {
    // 执行下单操作
    decr count;
}

我们借助事务操作就可以实现类似如下功能:

开启事务
get count;
if (count > 0) {
    // 执行下单操作
    decr count;
}
执行事务;

这样一来,当服务器接收到第二个客户端的"执行事务"命令时,第一个客户端的事务已经执行完毕,此时第二个客户端获取到的count就是正确的,也就避免了超卖问题。但是这里我们还需要想一想,Redis如何支持if条件判断语句呢?由于Redis支持原生Lua脚本,可以搭配Lua脚本进行if条件判断(感兴趣的小伙伴自行了解)

3. Redis事务操作

开启事务:MULTI
执行事务:EXEC
放弃当前事务:DISCARD
image.png
我们使用MULTI开启事务,并添加了两个key,但是并没有执行事务,此时如果使用第二个客户端进行访问,获取不到k1与k2的值:
image.png
但是当我们使用EXEC执行事务后,第二个客户端就可以进行访问了
image.png

温馨提示:如果在事务开启之后,突然断电,相当于执行了DISCARD丢弃当前事务操作!

4. watch监视原理

我们可以使用WATCH命令用来监视某个key是否在事务执行之前发生了变化:
image.png
在当前客户端上我们先使用watch k1监视k1键,此时第二个客户端执行了set k1 111此时当第一个客户端执行事务后,发现k1已经被改了于是返回nil,不执行set k1 222命令。
watch实现原理:类似于乐观锁,即预估当前发生锁冲突的概率不是很高,加锁操作的成本也比较低
watch中的乐观锁是基于 “版本号” 这样的机制实现的:

  1. 一开始客户端1执行watch k1时就会给k1分配一个版本号(递增的数字),例如为1,之后使用MULTI开始事务
  2. 这时客户端2执行SET k1 111修改了k1,此时版本号增长为2(由于客户端1此时还没有执行EXEC命令,因此由客户端2先执行)
  3. 此时客户端1执行EXEC命令,首先判断当时记录的k1的版本号是否与当前版本号一致,如果不一致说明有其余客户端更改,则返回nil,不执行事务中的内容;如果一致则继续执行

这个思想方法也与CAS的ABA问题解决方式相类似

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

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

相关文章

用神经网络求解微分方程

微分方程是物理科学的主角之一,在工程、生物、经济甚至社会科学中都有广泛的应用。粗略地说,它们告诉我们一个量如何随时间变化(或其他参数,但通常我们对时间变化感兴趣)。我们可以了解人口、股票价格,甚至…

【Java面向对象】二进制I/O

文章目录 1.二进制文件2.二进制 I/O 类2.1 FileInputStream 和 FileOutputStream2.2 FilterInputStream和 FilterOutputStream2.3 DatalnputStream 和 DataOutputStream2.4 BufferedInputStream 和 BufferedOutputStream2.5 ObjectInputStream 和 ObjectOutputStream 2.6 Seria…

深入理解 Linux Zero-copy 原理与实现策略图解

用户态和内核态 一般来说,我们在编写程序操作 Linux I/O 之时十有八九是在用户空间和内核空间之间传输数据,因此有必要先了解一下 Linux 的用户态和内核态的概念。 从宏观上来看,Linux 操作系统的体系架构分为用户态和内核态(或者…

昇思25天学习打卡营第24天|ResNet50迁移学习

课程打卡凭证 迁移学习 迁移学习是机器学习中一个重要的技术,通过在一个任务上训练的模型来改善在另一个相关任务上的表现。在深度学习中,迁移学习通常涉及在一个大型数据集(如ImageNet)上预训练的模型上进行微调,以便…

设计模式之策略模式_入门

前言 最近接触了优惠券相关的业务,如果是以前,我第一时间想到的就是if_else开始套,这样的话耦合度太高了,如果后期添加或者删除优惠券,必须直接修改业务代码,不符合开闭原则,这时候就可以选择我…

vue3.0学习笔记(一)——vue3简介与vite脚手架的使用

1. 为什么学vue3 Vue3现状: vue-next 2020年09月18日,正式发布vue3.0版本。但是由于刚发布周边生态不支持,大多数开发者处于观望。现在主流组件库都已经发布了支持vue3.0的版本,其他生态也在不断地完善中,这是趋势。…

Python | Leetcode Python题解之第268题丢失的数字

题目: 题解: class Solution:def missingNumber(self, nums: List[int]) -> int:n len(nums)total n * (n 1) // 2arrSum sum(nums)return total - arrSum

Qt第十三章 目录和文件操作

目录和文件操作 文章目录 目录和文件操作设备I/O简介I/O设备的类型基本文件读写QFileQTemporaryFile 流操作QTextStreamQDataStream QFileInfoQDirQFileSystemWatcherQStandardPathsQSettings 设备I/O 简介 I/O设备的类型 基本文件读写 QFile QFile file("C:/Users/PV…

Cisco 路由重发布 —— 实现路由信息在不同路由域间的传递

一、技术背景 在实际的组网中,可能会遇到这样一个场景:在一个网络中同时存在两种或者两种以上的路由协议。例如客户的网络原先是纯 Cisco 的设备,使用 EIGRP 协议将网络的路由打通。但是后来网络扩容,增加了一批华为的设备&#…

HAL库源码移植与使用之低功耗模式

低功耗特性对用电池供电的产品: 更小电池体积(降低了大小和成本) 延长电池寿命 电磁干扰更小,提高无线通信质量 电源设计更简单,无需过多考虑散热问题 电源供电区分为: 分为VDD供电区…

平面五杆机构运动学仿真matlab simulink

1、内容简介 略 89-可以交流、咨询、答疑 2、内容说明 略 ] 以 MATLAB 程序设计语言为平台 , 以平面可调五杆机构为主要研究对象 , 给定机构的尺寸参数 , 列出所 要分析机构的闭环矢量方程 , 使用 MATLAB 软件中 SIMULINK 仿真工具 , 在 SIMULINK 模型窗口下建立数…

深入理解TensorFlow底层架构

目录 深入理解TensorFlow底层架构 一、概述 二、TensorFlow核心概念 计算图 张量 三、TensorFlow架构组件 前端 后端 四、分布式计算 集群管理 并行计算 五、性能优化 内存管理 XLA编译 六、总结与展望 深入理解TensorFlow底层架构 一、概述 TensorFlow是一个开…

从0开始的STM32HAL库学习8

PWM控制舵机 配置环境 1. 选择TIM2时钟 2.选择内部时钟模式,打开通道二 3.分频系数PSC:72-1 自动重装寄存器ARR:20000-1 输出比较寄存器 CCR:500~2500( 后面可调整 ) 脉冲选择500后期可以改 编辑代码 调用启动函数 HAL_TIM_PWM_Start(&htim2,TIM_CHANN…

一分钟图情论文:《智慧数据视角下古籍数字出版的创新路径》

由武汉大学的雷珏莹和王晓光合著的《智慧数据视角下古籍数字出版的创新路径研究》论文从智慧数据1的视角出发,探讨了我国古籍数字出版的现状及其发展瓶颈,提出了古籍数字出版在内容、形式、服务和技术四个方面的创新路径。 文中, 研究者首先详细分析了当…

使用Fiddler进行Android和IOS抓包

Android抓包 要使用Telerik Fiddler Classic捕获Android设备的网络流量,您需要执行以下步骤: 在Fiddler Classic上进行设置: 确保已安装并使用BouncyCastle作为证书生成器。较新的Android版本会拒绝有效期超过两年的证书,目前只…

构建本地智能知识问答系统:基于Langchain和ChatGLM的简单实践

在数字化时代,智能知识问答系统成为了提升企业效率和数据安全性的关键工具。本文将介绍如何基于Langchain和ChatGLM构建一个本地化、支持中文的智能知识问答系统。该系统不仅能够实现完全本地化推理,而且对开源模型友好,可满足企业对数据隐私…

Windows中修改pip下载源

目录 一. 打开此电脑或文件管理器,输入 %APPDATA% 回车跳转 二. 在此目录中新建一个文件夹命令为pip 三. 进入这个目录,新建一个pip.ini文件 四. 复制阿里云镜像配置 五. CMD终端下载验证 六. 常用的国内镜像网站 一. 打开此电脑或文件管理器…

编程中的智慧六:单例、原型、建造者

上一篇咱们结合Spring介绍了设计模式中的工厂模式相关方法,其实现在Java开发基本上都是基于Spring框架开发,所以后续我们在开发过程中基本上很少自己重写一个工厂模式,都是直接使用Spring来完成。今天咱们接着看剩下的创建型设计模式&#xf…

配置VS+VLC并播放视频

文章目录 前言配置VSVLCVLC播放视频基本流程1. libvlc_new2. libvlc_set_user_agent3. libvlc_set_log_verbosity4. libvlc_media_new_path5. libvlc_media_player_new_from_media6. libvlc_media_player_play7. libvlc_media_player_get_state8. libvlc_media_release9. libvl…

使用9种方法隐藏和显示元素

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>使用9种方法隐藏和显示元素</title><sty…