[Redis] Redis事务
🌸个人主页:https://blog.csdn.net/2301_80050796?spm=1000.2115.3001.5343
🏵️热门专栏:
🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm=1001.2014.3001.5482
🍕 Collection与数据结构 (92平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm=1001.2014.3001.5482
🧀线程与网络(96平均质量分) https://blog.csdn.net/2301_80050796/category_12643370.html?spm=1001.2014.3001.5482
🍭MySql数据库(93平均质量分)https://blog.csdn.net/2301_80050796/category_12629890.html?spm=1001.2014.3001.5482
🍬算法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12676091.html?spm=1001.2014.3001.5482
🍃 Spring(97平均质量分)https://blog.csdn.net/2301_80050796/category_12724152.html?spm=1001.2014.3001.5482
🎃Redis(97平均质量分)https://blog.csdn.net/2301_80050796/category_12777129.html?spm=1001.2014.3001.5482
🐰RabbitMQ(97平均质量分) https://blog.csdn.net/2301_80050796/category_12792900.html?spm=1001.2014.3001.5482
感谢点赞与关注~~~
目录
- 1. Redis事务特性
- 2. Redis事务的意义
- 3. Redis事务实际操作
1. Redis事务特性
我们在之前学习MySQL和Spring的时候曾经接触过事务,我们知道,事务就是把好几个操作打包成为一个操作一起执行.这里的Redis的事务也是相同的道理.
我们在之前学习MySQL的事务的时候,我们知道MySQL的事务有4个特性,分别是原子性,一致性,持久性,隔离性.原子性就是把多个操作打包成为一个操作,要不都执行成功,要不都执行失败,一致性就是事务执行之前和执行之后数据都是合法的, 不可以出现某种中间的情况.持久性就是把数据保存在硬盘中,隔离性涉及到了事务的并发执行,隔离分为4个级别,分别是脏读,不可重复读,幻读,串行化.
但是Redis相比于MySQL的事务,就显得非常逊色.
- 首先原子性,Redis的事务,是否存在原子性,存在争议.Redis的事务虽然和MySQL一样,都是把多个操作打包为了一个操作.但是MySQL的事务在其中的操作出现一些异常的时候,数据都会回滚回去.要不全都执行成功,要不全部执行不成功.但是Redis中的事务如果有操作执行失败的时候,不具有回滚机制.也就是Redis的事务不具有要不都执行成功,要不都执行不成功的特性.Redis的这个原子性也就相当于MySQL原子性的一个半成品.
- 其次一致性,由于Redis没有约束,也没有回滚机制,如果事务执行过程中某个操作出现了失败,就可能引起数据不一致的情况.
- 不具备持久性,Redis本身就是内存数据库,数据是存在内存中的.虽然事务具有持久化的机制,但是这和事务没有关系.
- 最后不具备隔离性,Redis是一个单线程模型的服务程序,不存在并发的过程,所有的请求/事务都是串行化执行的.
2. Redis事务的意义
这么多特性Redis都不具备,那么Redis的事务到底有什么意义呢?
Redis的事务最主要的意义就是为了"打包",避免其他客户端的命令插队到中间.
Redis实现事务的时候引入了队列.每个客户端都有一个队列.开启事务的时候,此时客户端输入的命令就会发个服务器并且进入了这个队列中,而不是立即执行.当遇到"执行事务"的命令的时候,此时就会把队列中的这些任务都按照顺序依次执行.执行这些事务的时候是在Redis主线程中完成的.主线程会把事务中的操作都执行完,再处理别的客户端.

虽然Redis事务的功能没有MySQL强大,但是MySQL的事务为了完成这些强大的功能,也付出了不小的代价,空间上,需要花费更多的空间来存储更多的数据.时间上,也需要有更大的执行开销.
正是因为MySQL的事务有上述的问题,才有了Redis上场的机会.
比如下面的场景:
我们需要在购物网站上秒杀一个东西,就有可能出现超卖的情况,就是商家放了5000个商品,下单成功了5001个就是超卖.为了避免这样的情况,我们在多线程的章节,曾经通过上锁的方式来避免这样的情况.如果我们引入了Redis的话,我们可以直接使用事务即可解决.
比如两个客户端都在临界情况下下了单.
当客户端1开启一个事务的时候,事务1就会被放入到Redis的事务队列中,当客户端2也开启了一个事务的时候,事务2也会被放到队列中.事务1收到执行事务的命令被执行之后,count–,在事务2执行的时候,count>0的条件就不满足了,所以事务2就会执行失败.
上面的案例中,虽然Redis不具有if判断条件这样编程语言的功能.但是Redis可以引入lua脚本.通过lua脚本的方式就可以实现上述条件的判断.
3. Redis事务实际操作
- 开启事务
multi. - 执行事务
exec - 放弃当前事务
discard
127.0.0.1:6379[2]> keys *
(empty array)
127.0.0.1:6379[2]> MULTI
OK
127.0.0.1:6379[2]> set key1 value1
QUEUED
127.0.0.1:6379[2]> set key2 value2
QUEUED
我们看到,在事务中set key之后,会出现一个QUEUED,这就证明了该指令已经被放入了队列中,但是还没有被执行.如果我们另外打开一个客户端的话,发现这几个key并没有被设置.
127.0.0.1:6379> SELECT 2
OK
127.0.0.1:6379[2]> keys *
(empty array)
在我们执行了exec命令之后,才会执行事务.
127.0.0.1:6379[2]> EXEC
1) OK
2) OK
127.0.0.1:6379[2]> keys *
1) "key2"
2) "key1"
如果使用discard命令,事务就会被放弃.
127.0.0.1:6379[2]> MULTI
OK
127.0.0.1:6379[2]> set key3 value3
QUEUED
127.0.0.1:6379[2]> set key4 value4
QUEUED
127.0.0.1:6379[2]> DISCARD
OK
127.0.0.1:6379[2]> keys *
1) "key2"
2) "key1"
注意: 要是我们在开启事务的过程中,没有提交事务,而是重新启动了Redis服务器,那么该事务就和discard的效果一样,直接被抛弃了.
但是有时候会出现以下的情况,比如在一个客户端1的事务中,我们设置了一个key,value值为222,但是在客户端1的事务还没有提交的时候,客户端2中设置了key的value值为333.此时客户端1对事务进行了提交.此时key的值就被重新设置为了222.

127.0.0.1:6379[2]> MULTI
OK
127.0.0.1:6379[2]> set key3 333
QUEUED
127.0.0.1:6379[2]> set key3 222
OK
127.0.0.1:6379[2]> EXEC
1) OK
127.0.0.1:6379[2]> get key3
"333"
这时候,我们就需要引入一个操作watch,这个watch的用途就是监控某个key是否在开启事务之后,执行事务之前发生了改变.想要在事务中监控某个key,避免在另一个客户端修改key,我们就可以在事务开启之前使用watch key操作.我们把刚才的操作引入watch再来操作一次.
127.0.0.1:6379[2]> del key3
(integer) 1
127.0.0.1:6379[2]> MULTI
OK
127.0.0.1:6379[2]> set key3 333
QUEUED
127.0.0.1:6379[2]> set key3 222
OK
127.0.0.1:6379[2]> EXEC
(nil)
我们看到,如果在事务提交之前,被watch的key如果在另一个客户端被修改之后,最后提交事务的时候,就会返回一个nil.证明这个事务执行是失败的.
那么watch的实现原理是怎样的呢?其实watch的实现原理就类似于我们在之前并发编程中学习的乐观锁的实现,即"解决CAS中的ABA问题"的策略.
和ABA问题中的实现策略一样,Redis的watch就相当于是基于版本号这样的机制,来实现了乐观锁.
还是那上面的例子.在watch key3之后,Redis就会记录key3的版本号,开启事务之后,如果在其他的客户端修改了key3的值,那么key3的版本号就会改变,在提交事务的时候,事务就会发现watch的key的版本号发生了改变,于是事务就会执行失败.watch本质上就是给exec加上了一个对特定key的判定条件.

举例说明:判断老公是否出轨.
离开家之前,把枕头放到一个特定的位置,拍一张照片,如果回来之后,枕头的位置发生了改变,则证明老公出轨了.
相关文章:
[Redis] Redis事务
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
编译原理第一次实验报告
源代码及附件:编译原理实验一源程序及附件资源-CSDN文库实验题目 实验要求 实验设计 前两部分指出了实验的宏观把控,为了具体实施实验,我们需要预先为实验做出如下设计: 本次实验我选取了C语言的一个子集进行设计词法分析器&…...
uniapp的video视频属性打包app后层级过高
问题:在使用uniapp开发APP时,使用video标签显示视频发现H5可以正常展示,但是打包到APP后,它的层级过高,把底部导航都盖住了。 官网说明:uni-app官网 官网给了cover-view组件或plus.nativeObj.view、subNVue…...
问:Redis为什么这么快?
Redis,全称Remote Dictionary Server,是一个开源的高性能键值对数据库。它以其卓越的性能、丰富的数据结构和灵活的使用方式,在现代互联网应用中扮演着重要角色。本文将探讨Redis之所以快的原因,包括其数据结构、内存管理、IO多路…...
环信鸿蒙IM SDK实现附件消息发送与下载
环信HarmonyOS IM SDK 正式版已经发布,该版本全面覆盖即时通讯(IM)的核心功能,为用户提供了完整的IM全功能体验,同时支持从Android APK到 NEXT 的数据迁移,更好地满足企业在不同业务场景下的适配需求。 点…...
探索NetCat:网络流量监测与数据传输的利器
从简单的数据传输到复杂的网络调试,NetCat的灵活性和多功能性让人赞叹不已,在这篇文章中我将深入探讨NetCat的魅力,揭示它的基本功能、实用技巧以及在日常工作中的应用场景,发现如何用这一小工具提升的网络技能与效率。 目录 Net…...
【运动的&足球】足球运动员球守门员裁判检测系统源码&数据集全套:改进yolo11-DBBNCSPELAN
改进yolo11-FocalModulation等200全套创新点大全:足球运动员球守门员裁判检测系统源码&数据集全套 1.图片效果展示 项目来源 人工智能促进会 2024.10.28 注意:由于项目一直在更新迭代,上面“1.图片效果展示”和“2.视频效果展示…...
求最大公约数,最小公倍数
输入两个正整数 m 和 n,求其最大公约数和最小公倍数。 求最小公倍数算法: 最小公倍数 两整数的乘积 最大公约数 根据求最小公倍数的算法,可以看出如果已知最大公约数,就能很容易求出最小公倍数。而通过辗转相除法和相减法&#…...
Android——横屏竖屏
系统配置变更的处理机制 为了避免横竖屏切换时重新加载界面的情况,Android设计了一中配置变更机制,在指定的环境配置发生变更之时,无需重启活动页面,只需执行特定的变更行为。该机制的视线过程分为两步: 修改 Androi…...
scala---10.30
val、var package com_1030class Person {var name:String"rose"def sum(n1:Int,n2:Int):Int{n1n2} } object Person{def main(args: Array[String]): Unit {//创建person对象var personnew Person()println(person.sum(10,20))//30println(person.name)person.nam…...
Pinctrl子需要中client端使用pinctrl过程的驱动分析
往期内容 本专栏往期内容: Pinctrl子系统和其主要结构体引入Pinctrl子系统pinctrl_desc结构体进一步介绍Pinctrl子系统中client端设备树相关数据结构介绍和解析inctrl子系统中Pincontroller构造过程驱动分析:imx_pinctrl_soc_info结构体 input子系统专栏…...
【网络】传输层协议TCP
目录 四位首部长度 序号 捎带应答 标记位 超时重传机制 连接管理机制(RST标记位) 三次握手及四次挥手的原因 TCP的全称是传输控制协议(Transmission Control Protocol),也就是说,对于放到TCP发送缓冲…...
00-开发环境 MPLAB IDE 配置
MPLAB IDE V8.83 File 菜单简介 New (CtrlN): 创建一个新文件,用于编写新的代码。 Add New File to Project...: 将新文件添加到当前项目中。 Open... (CtrlO): 打开现有文件。 Close (CtrlE): 关闭当前打开的文件。 …...
<meta property=“og:type“ content=“website“>
<meta property"og:type" content"website"> 这段代码是HTML中的一部分,具体来说,它是一个用于定义Open Graph协议的meta标签。 代码分析 <meta> 标签:这是一个HTML标签,用于在HTML文档的头…...
C++ 实现俄罗斯方块游戏
✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…...
QT打包Macosx应用发布App Store简易流程
1、QC里编译工程,生成Release版的的app文件; 2、运行macdeployqt把需要的文件打包进app文件中; % ~/Qt/5.15.0/clang_64/bin/macdeployqt {编译的app文件所在路径}/Release/xxxx.app 3、使用codesign对app进行签名,如果要发App…...
untiy mlagents 飞机大战 ai训练
前言 之前那个python源码的飞机大战bug过多,还卡顿,难以继续训练。可直接放弃的话又不甘心,所以找了个unity版本的飞机大战继续(终于不卡了),这次直接使用现成的mlagents库。 过程 前前后后花了两周时间,甚至因此拖…...
从0开始学统计-什么是中心极限定理
引言 中心极限定理(Central Limit Theorem, CLT)是统计学中的一块基石,它揭示了一个难以置信的数学现象:无论一个随机变量的原始分布如何,只要我们取足够大的样本量,这些样本的平均值(或总和&a…...
工具方法 - 个人活动的分类
人类活动的分类是一个复杂的话题,因为人类的活动范围非常广泛且相互交叉。然而,我们可以尝试将人类的活动大致分为以下几个主要类别: 工作活动 工作活动是人类生活中不可或缺的一部分,通常包括以下方面: 1. 职业工作&a…...
11.1组会汇报-基于区块链的安全多方计算研究现状与展望
基础知识 *1.背书,这个词源来自银行票据业务,是指票据转让时,原持有人在票据背面加盖自己的印鉴,证明该票据真实有效、如果有问题就可以找原持有人。 区块链中的背书就好理解了。可以简单的理解为验证交易并声明此交易合法&…...
别再死记硬背了!用这5个真实项目案例,彻底搞懂Python函数参数与返回值
别再死记硬背了!用这5个真实项目案例,彻底搞懂Python函数参数与返回值 函数是Python编程的基石,但很多初学者在学完基础语法后,面对实际项目依然无从下手。本文将通过5个真实开发场景,带你从"会用"到"懂…...
Kubernetes部署Valheim游戏服务器:云原生架构实践指南
1. 项目概述:当维京英灵殿遇上Kubernetes如果你和我一样,既沉迷于《英灵神殿》(Valheim)里那种与三五好友一起伐木、采矿、建造长屋,然后被巨魔追得满地图跑的原始乐趣,又恰好是一名整天和容器、编排系统打…...
告别内置ADC的烦恼:用ADS1119搞定STM32/DSP的高精度电压采样(附完整代码)
告别内置ADC的烦恼:用ADS1119搞定STM32/DSP的高精度电压采样(附完整代码) 在嵌入式系统开发中,电压采样是基础却至关重要的环节。许多工程师在使用STM32或DSP内置ADC时,常会遇到精度不足、抗干扰能力差、无法测量差分信…...
TongWEB(东方通)实战:从零部署企业级WEB前后端项目
1. 环境准备:银河麒麟系统下的基础搭建 在银河麒麟桌面系统V10(SP1)兆芯版上部署企业级WEB项目,环境准备是第一步。我遇到过不少开发者直接跳过环境检查就急着部署,结果浪费大量时间排查兼容性问题。这里分享几个关键点: 首先是系…...
从纹波和EMI出发:实战分析DC-DC降压电路中PWM与PFM的取舍与优化技巧
从纹波和EMI出发:实战分析DC-DC降压电路中PWM与PFM的取舍与优化技巧 在射频模块或高精度ADC供电设计中,电源的纯净度直接决定系统性能上限。当输出电压纹波超出ADC的LSB范围,或EMI噪声耦合到敏感信号链时,工程师往往需要重新审视D…...
Translumo:5分钟掌握Windows实时屏幕翻译终极指南
Translumo:5分钟掌握Windows实时屏幕翻译终极指南 【免费下载链接】Translumo Advanced real-time screen translator for games, hardcoded subtitles in videos, static text and etc. 项目地址: https://gitcode.com/gh_mirrors/tr/Translumo 你是否在玩外…...
深度学习图像风格迁移:从Gatys算法到PyTorch工程实践
1. 项目概述:一个基于深度学习的图像风格迁移应用最近在GitHub上闲逛,发现了一个名为“aristoapp/DDalkkak”的项目。单看这个名字,可能有点摸不着头脑,但点进去一看,发现这是一个关于图像风格迁移(Image S…...
AI智能体操作安卓设备:基于agent-droid-bridge的自动化实践
1. 项目概述:连接AI与安卓设备的桥梁 最近在折腾AI智能体(Agent)和自动化流程时,遇到了一个挺有意思的需求:如何让运行在服务器上的AI程序,直接去操作一台真实的安卓手机或模拟器,完成一些复杂的…...
基于React的记忆管理UI组件库:openclaw-memory-ui实战指南
1. 项目概述:一个为记忆管理而生的开源UI组件库最近在折腾一个需要处理大量结构化记忆数据的项目,比如知识库、笔记应用或者智能助手的历史对话管理。这类应用的核心痛点在于,数据本身是复杂的、多维的,但传统的列表或表格展示方式…...
基于声明式Web自动化框架Hydra的电商数据监控实战
1. 项目概述:一个被低估的自动化利器 如果你经常需要处理一些重复性的、基于Web界面的操作,比如批量下载某个网站的资源、定时填写表单、或者监控网页内容的变化,那么你很可能已经厌倦了手动点击和等待。传统的脚本编写,尤其是涉及…...


