当前位置: 首页 > news >正文

[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事务实际操作

  1. 开启事务multi.
  2. 执行事务exec
  3. 放弃当前事务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中的一部分&#xff0c;具体来说&#xff0c;它是一个用于定义Open Graph协议的meta标签。 代码分析 <meta> 标签&#xff1a;这是一个HTML标签&#xff0c;用于在HTML文档的头…...

C++ 实现俄罗斯方块游戏

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

QT打包Macosx应用发布App Store简易流程

1、QC里编译工程&#xff0c;生成Release版的的app文件&#xff1b; 2、运行macdeployqt把需要的文件打包进app文件中&#xff1b; % ~/Qt/5.15.0/clang_64/bin/macdeployqt {编译的app文件所在路径}/Release/xxxx.app 3、使用codesign对app进行签名&#xff0c;如果要发App…...

untiy mlagents 飞机大战 ai训练

前言 之前那个python源码的飞机大战bug过多&#xff0c;还卡顿&#xff0c;难以继续训练。可直接放弃的话又不甘心&#xff0c;所以找了个unity版本的飞机大战继续(终于不卡了)&#xff0c;这次直接使用现成的mlagents库。 过程 前前后后花了两周时间&#xff0c;甚至因此拖…...

从0开始学统计-什么是中心极限定理

引言 中心极限定理&#xff08;Central Limit Theorem, CLT&#xff09;是统计学中的一块基石&#xff0c;它揭示了一个难以置信的数学现象&#xff1a;无论一个随机变量的原始分布如何&#xff0c;只要我们取足够大的样本量&#xff0c;这些样本的平均值&#xff08;或总和&a…...

工具方法 - 个人活动的分类

人类活动的分类是一个复杂的话题&#xff0c;因为人类的活动范围非常广泛且相互交叉。然而&#xff0c;我们可以尝试将人类的活动大致分为以下几个主要类别&#xff1a; 工作活动 工作活动是人类生活中不可或缺的一部分&#xff0c;通常包括以下方面&#xff1a; 1. 职业工作&a…...

11.1组会汇报-基于区块链的安全多方计算研究现状与展望

基础知识 *1.背书&#xff0c;这个词源来自银行票据业务&#xff0c;是指票据转让时&#xff0c;原持有人在票据背面加盖自己的印鉴&#xff0c;证明该票据真实有效、如果有问题就可以找原持有人。 区块链中的背书就好理解了。可以简单的理解为验证交易并声明此交易合法&…...

ubuntu【桌面】 配置NAT模式固定IP

DHCP分配导致虚拟机IP老变&#xff0c;SSH老要重新配置&#xff0c;设成静态方便些 一、设NAT模式 1、设为NAT模式 2、看模式对应的虚拟网卡 - VMnet8 3、共享主机网卡网络到虚拟网卡 - VMnet8 二、为虚拟网卡设置静态IP 记住这个IP 三、设置ubuntu固定IP 1、关闭DHCP并…...

评估 机器学习 回归模型 的性能和准确度

回归 是一种常用的预测模型&#xff0c;用于预测一个连续因变量和一个或多个自变量之间的关系。 那么&#xff0c;最后评估 回归模型 的性能和准确度非常重要&#xff0c;可以帮助我们判断模型是否有效并进行改进。 接下来&#xff0c;和大家分享如何评估 回归模型 的性能和准…...

如何下载安装TestLink?

一、下载TestLink、XAMPP TestLink 下载 |SourceForge.net 备用&#xff1a;GitHub - TestLinkOpenSourceTRMS/testlink-code&#xff1a; TestLink开源测试和需求管理系统 下载XAMPP&#xff1a; Download XAMPP 注意&#xff1a;TestLink与PHP版本有关系&#xff0c;所以XA…...

基于SSM+微信小程序的订餐管理系统(点餐2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的订餐管理系统实现了管理员和用户。管理端实现了 首页、个人中心、用户管理、菜品分类管理、菜品信息管理、订单信息管理、配送信息管理、菜品评价管理、订单投诉管理、…...

【C++排序 双指针】1996. 游戏中弱角色的数量|1996

本文涉及的基础知识点 排序 C算法&#xff1a;滑动窗口及双指针总结 本题其它解法 【C单调栈 排序】1996. 游戏中弱角色的数量|1996 LeetCode1996. 游戏中弱角色的数量 你正在参加一个多角色游戏&#xff0c;每个角色都有两个主要属性&#xff1a;攻击 和 防御 。给你一个…...

GESP4级考试语法知识(捕捉异常)

参考程序代码&#xff1a; #include <iostream> using namespace std;double divide(double a, double b) {if (b 0) {throw "Division by zero error"; // 抛出异常}return a / b; }int main() {double num1, num2;cout << "Enter two numbers:…...

HTML 基础标签——元数据标签 <meta>

文章目录 1. `<meta>` 标签概述2. 属性详解2.1 `charset` 属性2.2 `name` 属性2.3 `content` 属性2.4 `http-equiv` 属性3. 其他常见属性小结在 HTML 文档中,元数据标签 <meta> 是一种重要的标签,用于提供关于文档的信息,这些信息不直接显示在网页内容中,但对于…...

栈虚拟机和寄存器虚拟机,有什么不同?

本来这节内容是打算直接讲字节码指令的&#xff0c;但讲之前又必须得先讲指令集架构&#xff0c;而指令集架构又分为两种&#xff0c;一种是基于栈的&#xff0c;一种是基于寄存器的。 那不妨我们这节就单独来讲讲栈虚拟机和寄存器虚拟机&#xff0c;它们有什么不同&#xff0…...

Windows下基于fping进行批量IP测试

fping是Linux下一个很好用的IP测试工具&#xff0c;结合代码可以完成批量的IP测试&#xff0c;在网络调试中用途很广。本文是基于fping for Windows结合bat批处理&#xff0c;定制的测试脚本样例。 一、程序信息 本次测试使用fpingV5.1 for Windows版&#xff0c;版本信息如下…...

一款实用的Word文档图片转换与水印保护工具

目录 前言软件功能简介软件实现方法及关键代码 1. Word 文档转图片的实现2. 图片水印添加功能3. 生成数字指纹&#xff08;哈希值&#xff09;4. 保存图片信息到 JSON 文件 软件的实际使用场景软件操作指南 1. 下载和安装2. 操作流程 总结 1&#xff0c;前言 在日常办公和内…...