【Redis 进阶】事务

news2024/12/23 22:24:17

Redis 的事务和 MySQL 的事务概念上是类似的,都是把一系列操作绑定成一组,让这一组能够批量执行。


一、Redis 的事务和 MySQL 事务的区别

1、MySQL 事务

  • 原子性:把多个操作打包成一个整体。(要么全都做,要么都不做)
  • ⼀致性:事务执行前和执行后,数据得保持相同
  • 隔离性:事务并发执行涉及到的一些问题(脏读、幻读等)。
  • 持久性:事务中做出的修改都会存储到硬盘中。

2、Redis 的事务

  • 弱化的原子性:redis 没有 “回滚机制”,只能做到这些操作 “批量执行”,不能做到 “一个失败就恢复到初始状态”,也就是无法保证执行成功。(网上有的说 Redis 事务有原子性(只是打包一起执行),有的说没有原子性(打包一起执行 + 带有回滚 —— 打包一起正确执行))
  • 不保证⼀致性:不涉及 “约束”,也没有回滚(MySQL 的一致性体现的是运行事务前和运行后,结果都是合理有效的,不会出现中间非法状态)。事务在执行过程中如果某个修改操作出现失败,就可能引起不一致的情况。
  • 不需要隔离性:也没有隔离级别,因为不会并发执行事务(Redis 是一个单线程模型的服务器程序,所有的请求 / 事务都是 “串行” 执行的)。
  • 不需要持久性:Redis 本身就是内存数据库,数据是存储在内存中的。虽然 Redis 也有持久化机制,但是否开启持久化是 redis-server 自己的事情,和事务无关。

Redis 事务本质上是在服务器上搞了⼀个 “事务队列”,每次客户端在事务中进行一个操作,都会把命令先发给服务器,放到 “事务队列” 中,但并不会立即执行,而是在收到 EXEC 命令后,才按照顺序依次执行队列中的所有操作(在 Redis 主线程中完成的,主线程会把事务中的操作都执行完,再处理别的客户端)。

因此,Redis 的事务的功能相比于 MySQL 来说,是弱化很多的。只能保证事务中的这几个操作是 “连续的”,不会被别的客户端 “加塞”,仅此而已。


为什么 Redis 不设计成和 MySQL 一样强大呢?

MySQL 的事务付出了很大的代价:

  • 在空间上,需要花费更多的空间来存储更多的数据。
  • 在时间上,也要有更大的执行开销。

正是因为 Redis 简单、高效的特点,才能够在分布式系统中弥补一些 MySQL 不擅长的场景。


什么时候需要使用到 Redis 事务呢?

如果我们需要把多个操作打包进行,使用事务是比较合适的。之前在多线程中是通过加锁的方式来避免 “插队” 的,而在 Redis 中直接使用事务即可。

在上面这个场景没有加锁也能解决问题。

Redis 命令里能够进行类似上图中的条件判断吗?

Redis 原生命令中确实没有这种条件判断,但是 Redis 支持 lua 脚本。通过 lua 脚本就可以实现上述的条件判定,并且也和事务一样是打包批量执行的。

lua 脚本的实现方式是 Redis 事务的进阶版本,此处对 lua 脚本不做过多的讨论。

注意:如果 Redis 是按照集群模式部署的话,是不支持事务的。 


二、事务操作

1、MULTI

开启一个事务,执行成功返回 OK。


2、EXEC

真正执行事务。

每次添加一个操作,都会提示 "QUEUED",说明命令已经进入客户端的事务队列中。此时如果另外开一个客户端,再尝试查询这几个 key 对应的数据,是没有结果的:

只有当真正执行 EXEC 的时候,客户端才会真正把上述操作发送给服务器,此时就可以获取到上述 key 的值了。

此时,另一个客户端再次查询结果也是如此。


3、DISCARD

放弃当前事务,此时直接清空事务队列,之前的操作都不会真正执行到。

当开启事务并给服务器发送若干个命令之后,服务器重启,那么此时这个事务怎么办呢?

此时的效果就等同于 discard。


4、WATCH

在执行事务的时候,如果某个事务中修改的值被别的客户端修改了,此时就容易出现数据不一致的问题。

客户端 1 先执行:

客户端 2 再执行:

客户端 1 最后执行:

此时 key 的值是多少呢?

从输入命令的时间看,是客户端 1 先执行的 set key 222,客户端 2 后执行的 set key 333。但是从实际的执行时间来看,是客户端 2 先执行的,客户端 1 后执行的。

由于客户端 1 得是 exec 执行了,才会真正执行 set key 222,所以这个操作实际上更晚执行,最终值就是 222.

这个时候其实就容易引起歧义。因此,即使不保证严格的隔离性,至少也要告诉用户,当前的操作可能存在风险。watch 命令就是用来解决上述这个问题的,watch 在该客户端上监控一组具体的 key,看看这个 key 在事务的 multi 和 exec 之间,set key 之后,是否在外部被其他客户端修改了。

  • 当开启事务的时候,如果对 watch 的 key 进行修改,就会记录当前 key 的 “版本号”(版本号可以理解成一个整数,每次修改都会使版本变大,服务器来维护每个 key 的版本号情况)
  • 在真正提交事务的时候,如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号,就会让事务执行失败(事务中的所有操作都不执行)。

客户端 1 先执行:

watch 本质上是给 exec 加一个判定条件。

key 进行修改从服务器获取 key 的版本号是 0,记录 key 的版本号(还没真的修改,版本号不变)

这里只是入队列,但是不提交事务执行。

客户端 2 再执行:

修改成功,使服务器端的 key 的版本号 0 -> 1

客户端 1 最后执行:

exec 在执行上述事务中的命令时,此处就会做出判定。对比版本发现客户端的 key 的版本号是 0,服务器上的版本号是 1,版本不一致,说明有其他客户端在事务中间修改了 key,说明事务被取消了,于是真正执行 set key 222 的时候就没有真正执行。

客户端 2 执行:


(1)watch 的实现原理

watch 的实现类似于一个 “乐观锁”(不是指某个具体的锁,而指的是某一类锁的特性)。

  • 乐观锁(成本低):加锁之前就有一个心理预期,预期接下来锁冲突的概率比较低。
  • 悲观锁(成本高):加锁之前就有一个心理预期,预期接下来锁冲突(两个线程针对同一个锁加锁,一个能加锁成功,另一个就得阻塞等待)的概率比较高。

锁冲突概率高和冲突概率低,意味着接下来要做的工作是不一样的。

C++ Linux 中涉及到的锁 mutex / std::mutex 都是悲观锁,Java synchronized 则是可以在悲观和乐观之间自适应。


5、UNWATCH

取消对 key 的监控,相当于 WATCH 的逆操作。

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

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

相关文章

实时渲染云交互助力汽车虚拟仿真新体验!

汽车虚拟仿真是指利用软件和数学模型,模拟汽车的设计、制造、测试和运行等过程,以及汽车与环境、驾驶员、乘客等的交互。汽车虚拟仿真可以帮助汽车工程师快速验证方案,优化性能,降低成本,提高安全性和可靠性。 ​ 汽车…

S32G3系列芯片Serial Boot功能详解!

《S32G3系列芯片——Boot详解》系列——S32G3系列芯片Serial Boot功能详解!★★★ 一、Serial Boot模式概述二、串行下载协议2.1 基于UART和CAN的下载协议概述2.2 基于FlexCAN的Serial Boot2.2.1 IO配置2.2.2 时钟配置2.2.3 通信波特率2.2.4 基于FlexCAN的Serial Bo…

精心准备的高水平的博客【点评语】,来抄啊!

大家好,我是一名_全栈_测试开发工程师,已经开源一套【自动化测试框架】和【测试管理平台】,欢迎大家关注我,和我一起【分享测试知识,交流测试技术,趣聊行业热点】。 第 1 条 这篇博客文章如同灯塔般照亮了技…

ElementPlus 覆盖默认样式的探索

文章目录 问题解决:global 解释改进一下在研究一下 问题 解决 使用 :global(.el-header) :global(.el-header) {padding: 0; } :global(.el-menu--horizontal) {justify-content: center; }:global 解释 在Vue中,:global() 是一个特殊的 CSS 选择器,用…

在Windows中使用VS Code连接远程服务器

①首先生成自己的密钥 ssh-keygen ②打开VS Code的扩展,安装连接工具 Remote-SSH Remote - SSH: Editing Configuration Files ③点击左侧远程资源管理器,之后点击SSH右侧齿轮,选择一个配置文件 注意:此部分的Host名字要与生成…

【Python机器学习系列】一文教你实现决策树模型可视化(案例+源码)

这是我的第335篇原创文章。 一、引言 决策树是一个有监督分类模型,本质是选择一个最大信息增益的特征值进行输的分割,直到达到结束条件或叶子节点纯度达到阈值。根据分割指标和分割方法,可分为:ID3、C4.5、CART算法。每一种颜色代…

GitLab安装方式

一、什么是GitLab GitLab是一个利用Ruby on Rails开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开或者私人项目。它拥有与Github类似的功能,能够浏览源代码,管理缺陷和注释,可以管理团队对…

动态代理对象在 IronPython 中的实现

动态代理对象是一种设计模式,允许在运行时动态地创建对象,并在这些对象上拦截和处理方法调用。它常用于 AOP(面向方面编程)、日志记录、权限控制等场景。应用非常广泛,下面跟着我来聊一聊我遇到的问题。 1、问题背景 …

通过ProSave对西门子触摸屏进行OS更新的具体操作方法(恢复出厂设置)

通过ProSave对西门子触摸屏进行OS更新的具体操作方法(恢复出厂设置) 首先,打开电脑的控制面板,将右上角的查看方式修改为“大图标”,如下图所示,找到“设置PG/PC接口”, 如下图所示,在弹出的窗口中上方的应用程序访问点的下拉菜单中选择 “S7ONLINE(STEP7)”,并在下…

【深度学习实战(49)】目标检测损失函数:IoU、GIoU、DIoU、CIoU、EIoU、alpha IoU、SIoU、WIoU原理及Pytorch实现

前言 损失函数是用来评价模型的预测值和真实值一致程度,损失函数越小,通常模型的性能越好。不同的模型用的损失函数一般也不一样。损失函数主要是用在模型的训练阶段,如果我们想让预测值无限接近于真实值,就需要将损失值降到最低…

kernel-devel导致的linux网卡驱动安装异常

引言 安装包下载:iso镜像文件解压后进入package路径,可以找到所有想要的rpm安装包 1.检查gcc gcc -v:检查gcc编译程序是否安装,如果已经成功安装直接执行步骤3 2.安装gcc & gcc-c gcc程序准备,拷贝到centos后进入…

大厂linux面试题攻略五之数据库管理

一、数据库管理-MySQL语句 0.MySQL基本语句: 1.SQL语句-增 创建xxx用户: mysql>create user xxx % indentified by 123456; xxx表示用户名 %b表示该用户用来连接数据库的方式(远程或本地连接) indentified by 123456设置密码…

《看漫画学Python》全彩PDF教程,495页深度解析,零基础也能轻松上手!

前言 说起编程语言,Python 也许不是使用最广的,但一定是现在被谈论最多的。随着近年大数据、人工智能的兴起,Python 越来越多的出现在人们的视野中。 在各家公司里,Python 还常被用来做快速原型开发,以便更快验证产品…

PyCharm 中如何使用驭码CodeRider?

极狐GitLab 在 5 月 28 日正式发布了 AI 产品驭码CodeRider,可以使用驭码CodeRider 进行AI 编程 & DevOps 流程处理。现已开启免费试用,登录官网:https://coderider.gitlab.cn/ 即可申请试用。 GitLab 中文版学习资料 驭码CodeRider 官…

【论文学习】基于序列统计的未知无线协议特征提取方法

【参考文献】刘治国,蔡文珠,李运琪,等.基于序列统计的未知无线协议特征提取方法[J].计算机工程,2021,47(11):192-197.DOI:10.19678/j.issn.1000-3428.0059551.【注】本文仅为作者个人学习笔记,如有冒犯,请联系作者删除。 这篇题为《基于序列统计的未知无…

U-Net++原理与实现(含Pytorch和TensorFlow源码)

U-Net原理与实现 引言1. U-Net简介1.1 编码器(Encoder)1.2 解码器(Decoder)1.3 跳跃连接(Skip Connections) 2. U-Net详解2.1 密集跳跃连接2.2 嵌套和多尺度特征融合2.3 参数效率和性能2.4 Pytorch代码2.5 …

conda搭建环境,pycham使用

相信学习了tensorflowjs后一定不会满足,毕竟tensorflowjs使用场景以及开源度远不及pyhton的tensorflow,所以不要犹豫,开始使用python吧,有ChatGPT帮助,比想象的简单很多 python环境安装 conda环境安装 推荐大家直接…

[STM32][Bootloader][教程]STM32 HAL库 Bootloader开发和测试教程

0. 项目移植 对于不想知道其执行过程的朋友来说,可以直接移植,我的板子是STM32F411CER6, 512K M4内核 项目地址: Bootloader(可以自己写标志位用于自测,项目中这部分代码已经被注释,可以打开自行测试&…

中国智能物流头部集成商的“江湖地位”及其“独门秘笈”

导语 大家好,我是社长,老K。专注分享智能制造和智能仓储物流等内容。 物流仓储自动化领域犹如一片充满机遇与挑战的江湖,各大企业群雄逐鹿,各展所长。这些企业,如同金庸小说中的武林高手,不仅拥有深厚的内功…

后台列表复制功能

html&#xff1a; <el-button click"copy(row)">复制</el-button><!-- 复制弹框 --> <el-dialog :close-on-click-modal"false" title"复制" width"600px" :visible.sync"copyVisible" append-to-bod…