Redis事务操作

news2025/8/2 11:56:28

Redis事务操作

每个公司每个项目可能有不同的引入方式,但是最基本的都大差不差,所以这里只展示最基本的。

redis事务定义

redis事务是一个单独的隔离操作,事务中的所有命令都会序列化、按顺序地执行,事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。

redis事务的主要作用就是串联多个命令防止别的命令插队。

Multi、Exec、discard

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,redis会将之前的命令依次执行。

组队的过程中可以通过discard来放弃组队。

redis事务分2个阶段:组队阶段、执行阶段

  • 组队阶段:只是将所有命令加入命令队列
  • 执行阶段:依次执行队列中的命令,在执行这些命令的过程中,不会被其他客户端发送的请求命令插队或者打断。

相关的几个命令

multi:标记一个事务块的开始

标记一个事务块的开始。

事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由exec命令原子性(atomic)地执行。

示例:

127.0.0.1:6379> multi		#开启事务
OK
127.0.0.1:6379> incr id		#incr将id的值+1,id不存在会被初始化为0
QUEUED						#表示这个命令加入队列了,还没有被执行
127.0.0.1:6379> incr id
QUEUED
127.0.0.1:6379> incr id
QUEUED
127.0.0.1:6379> ping		#ping用来判断服务器运作正常的话,返回PONG
QUEUED
127.0.0.1:6379> exec		#以上几个命令依次执行
1) (integer) 1
2) (integer) 2
3) (integer) 3
4) PONG

exec:执行所有事务块内的命令

执行所有事务块内的命令。

假如某个(或某些)key正处于watch命令的监视之下,且事务块中有和这个(或这些)key相关的命令,那么exec命令只在这个(或这些)key没有被其他命令所改动的情况下执行并生效,否则该事务被打断(abort)。

如果exec执行成功,会返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值nil。

示例1:

#客户端1
127.0.0.1:6379> watch userid username	#监听userid和username
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set userid 1001			#设置userid为1001
QUEUED
127.0.0.1:6379> incr userid				#userid自加1
QUEUED
127.0.0.1:6379> exec					#单客户端下执行成功
1) OK
2) (integer) 1002

示例2:

#客户端1
127.0.0.1:6379> flushdb #方便测试
127.0.0.1:6379> watch userid username
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set userid 1001
QUEUED
#此时开启客户端2
#等待客户端2设置username之后,再执行exec
127.0.0.1:6379> exec
(nil)					#返回nil,是因为其他客户端操作了username,事务执行失败

#客户端2
127.0.0.1:6379> set username "张三" #将username设置为“张三”
OK

discard:取消事务

取消事务,放弃执行事务块内的所有命令。

示例:

redis> multi
OK
redis> ping
QUEUED
redis> SET hi "hello"
QUEUED
redis> discard
OK

事务的错误处理

情况1:组队中命令有误,导致所有命令取消执行

组队中某个命令出现了错误报告,执行时整个队列中所有的命令都会被取消。

示例代码:

#事务中执行了3个set命令,而第3个命令“set address”命令本身有问题,加入队列失败
#最后执行exec的时候,所有的命令都被取消执行。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> multi #开启一个事务块
OK
127.0.0.1:6379(TX)> set name ready
QUEUED
127.0.0.1:6379(TX)> set age 30
QUEUED
127.0.0.1:6379(TX)> set address #命令有问题,导致加入队列失败
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec #执行exec的时候,事务中所有命令都被取消
(error) EXECABORT Transaction discarded because of previous errors.

情况2:组队中没有问题,执行中部分成功部分失败

命令组队的过程中没有问题,执行中出现了错误会导致部分成功部分失败。

示例代码:

#事务中有3个命令,3个命令都入队列成功了
#执行exec命令的时候,1和3命令成功了,第2个失败了
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k1 v1 #命令1:设置k1的值为v1
QUEUED
127.0.0.1:6379(TX)> incr k1 #命令2:k1的值递增1,由于k1的值不是数字,执行的时候会失败的
QUEUED
127.0.0.1:6379(TX)> set k2 v2 #命令3:设置k2的值为v2
QUEUED
127.0.0.1:6379(TX)> exec #执行命令,1和3命令成功,第2个失败了
1) OK
2) (error) ERR value is not an integer or out of range
3) OK
127.0.0.1:6379> mget k1 k2 #查看k1和k2的值
1) "v1"
2) "v2"

事务冲突的问题

我们学习的时候经常会碰到这样的假设:账户中只有10000,有多个人使用你的账户,同时去参加双十一抢购

一个请求想给金额减8000

一个请求想给金额减5000

一个请求想给金额减1000

在这里插入图片描述

3个请求同时看到的余额都是10000,大于操作金额,都去执行修改余额的操作,最后导致金额变成了-4000,这显然是有问题的。

悲观锁

在这里插入图片描述

悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人拿到这个数据就会block直到它拿到锁。传统的关系型数据库里面就用到了很多这种锁机制,比如行锁、表锁、读锁、写锁等,都是在做操作之前先上锁。

乐观锁

在这里插入图片描述

乐观锁(Optimistic Lock),顾名思义,就是很乐观,每次去那数据的时候都认为别人不会修改,所以不会上锁,但是在修改的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁适用于多读的应用类型,这样可以提高吞吐量。redis就是使用这种check-and-set机制实现事务的。

watch key [key …]

在执行multi之前,先执行watch key1 [key2 …],可以监视一个或者多个key,若在事务的exec命令之前这些key对应的值被其他命令所改动了,那么事务中所有命令都将被打断,即事务所有操作将被取消执行。

上面章节以给出相关示例:

#客户端1
#客户端1用watch监控userid和username
127.0.0.1:6379> watch userid username
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set userid 1001
QUEUED
#此时开启客户端2
#等待客户端2设置username之后,再执行exec
127.0.0.1:6379> exec
(nil)					#返回nil,是因为其他客户端操作了username,事务执行失败



#客户端2执行操作
127.0.0.1:6379> set username "张三" #将username设置为“张三”
OK

unwatch:取消监视

取消watch命令对所有key的监视。

如果在执行watch命令之后,exec命令或discard命令先被执行了的话,那么就不需要再执行unwatch了。

因为exec命令会执行事务,因此watch命令的效果已经产生了;而discard命令在取消事务的同时也会取消所有对key的监视,因此这两个命令执行之后,就没有必要执行unwatch了。

示例:

127.0.0.1:6379> watch userid username
OK
127.0.0.1:6379> unwatch
OK

redis事务三特性

(1)单独的隔离操作

事务中的所有命令都会序列化、按顺序地执行,事务在执行过程中,不会被其他客户端发送来的命令请求所打断。

(2)没有隔离级别的概念

队列中的命令没有提交(exec)之前,都不会实际被执行,因为事务提交前任何指令都不会被实际执行。

(3)不能保证原子性

事务中如果有一条命令执行失败,后续的命令仍然会被执行,没有回滚。

如果在组队阶段,有1个失败了,后面都不会成功;如果在组队阶段成功了,在执行阶段有那个命令失败就这条失败,其他的命令则正常执行,不保证都成功或都失败。

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

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

相关文章

Rancher - v2.6.5升级v2.7.0

Rancher👉v2.6.5升级v2.7.0 时间:2022年11月18日16:37:50 2022-11-17凌晨,rancher推出了新的稳定版:v2.7.0。 一、为什么要升级到v2.7.0?v2.6.5有什么严重的问题吗? ● 对于私有云来说,一般生…

C51项目 - 可调万年历

目录一、实验目的二、实验仪器三、实验效果预览1.显示效果2.调节效果四、实验原理五、单片机代码1.头文件包含2.类型定义3.时钟模块4. 液晶显示模块5.温度传感器模块6. 红外通讯模块7.开机初始化8.特殊功能函数9.代码段常量10.完整代码一、实验目的 使用51单片机作为主控芯片&…

Hybrid app混合开发的一些经验和总结

随着5G技术的发展和移动终端普及,移动设备的便捷性和网络的泛在化,移动应用已广泛应用于电子商务、电子政务、医疗和辅助教学中。 智能手机等移动终端的存储、运算能力不断增强,但其显示、输入等不如PC灵活,对操作界面灵活性有强…

Redis 搭建高可用集群

、单个redis服务搭建请参考:redis服务搭建 2、在/usr/local下创建目录redis-cluster,并在redis-cluster下创建 6379、6380、6381目录以及data、temp目录 # cd /usr/local # mkdir redis-cluster --其他文件创建类似,此处不一一写出 3、复制安装后的re…

[笔记]快乐的Linux命令行《二》文件系统中跳转

系列文章目录 [笔记]快乐的Linux命令行《一》LInux系统简介以及什么是shell [笔记]快乐的Linux命令行《二》文件系统中跳转 文章目录系列文章目录前言一、文件系统中跳转1.1 理解文件系统树Linux基本文件系统树目录介绍与Windows的异同1.2 当前工作目录pwd 显示当前工作目录1.…

CSS基础入门

CSS基础入门 1.官方文档 1.CSS 指的是层叠样式表* (Cascading Style Sheets) 2.地址: https://www.w3school.com.cn/css/index.asp 2.为什么需要 CSS 1.在没有 CSS 之前,我们想要修改 HTML 元素的样式需要为每个 HTML 元素单独定义样式属性,费心费力…

手把手教你如何编写一个Makefile文件

一、概念理解(彩蛋藏在某个地方) 1.1 什么是Makefile? C语言中,我们使用visual studio开发软件时候,写程序开始时候都会创建一个project项目文件,然后在文件里面编译 .h 和 .c 的文件。在Linux中&#xf…

给大家免费发布几款苹果CMSv10模板影视主题,附带教程和演示截图

苹果CMS是优秀的开源PHP建站系统,在主流建站系统中特色鲜明,以灵活、小巧、兼容性好、负载强等优点而深受许多站长的喜爱。 很多人在运营苹果cms站点都会找模板,下面博主给大家推荐几款免费并且简约的模板,其实个人认为模板这东西不需要买太贵的&#xf…

编译安装LAMP架构搭建wordpress个人博客和discuz论坛——编译安装基于 FASTCGI 模式LAMP架构多虚拟主机WEB应用

文章目录1 实验目标2 环境准备3 实现步骤3.1.1 二进制安装3.1.2为wordprss和discuz应用准备数据库和用户帐号3.2 编译安装 httpd 2.43.3 编译安装 fastcgi 方式的 php 7.43.4 修改配置 httpd 支持 php-fpm3.5 准备wordpress和discuz! 相关文件3.6 测试访问3.7 安装成功1 实验目…

MySQL高级篇知识点——其它数据库日志

目录1.其他数据库日志1.1.日志类型1.2.日志的弊端2.慢查询日志 (slow query log)3.通用查询日志 (general query log)3.1.问题场景3.2.查看当前状态3.3.启动日志3.4.查看日志3.5.停止日志3.6.删除/刷新日志4.错误日志 (error log)4.1.启动日志4.2.查看日志4.3.删除/刷新日志5.二…

Glide图片框架源码解析

一、Glide几个基本概念 Model 表示数据的来源;加载图片的时候需要告诉Glide从哪获取这个图片,可以是url类型、本地文件类型、资源ID类型。不管什么类型,Glide都将其称为Model。 Data 从数据源中获取到model之后,把它加工成原始数…

java.swing 飞机大战小游戏

上午没事刷到网上最近炒热了一些简单的小游戏和爱心代码,单身8个月了,对爱心代码不是很感冒,所以想蹭个热度,写一个飞机大站来玩玩。 首先,分析小游戏需要那些技术与怎么设计: 窗体,因为是jav…

Python如何使用PyMySQL连接数据库

1:为什么要连接数据库呢? 做接口自动化测试的时候,我们需要校验数据是否正常入库,数据是否正确,来做断言处理;有的时候需要修改数据,去执行其他场景的测试用例;有的时候需要删除数据…

DOX-HSA/HGB/FITC/Glu人血清蛋白/血红蛋白/荧光素/葡萄糖修饰阿霉素

小编今天分享给大家的科研知识是DOX-HSA/HGB/FITC/Glu人血清蛋白/血红蛋白/荧光素/葡萄糖修饰阿霉素,来看! DOX-HSA人血清蛋白偶联阿霉素相关: 采用阿霉素(Doxorubicin,DOX)与人血清白蛋白(HSA)经化学交联获得的偶联物。本品经过滤,溶于PBS…

Chapter4 利用机器学习解决分类和回归问题

目录 4.1 机器学习和神经网络基本概念 4.1.1 感知器 4.1.2 前向传播 4.1.3 反向传播 4.1.4 过拟合和欠拟合 4.2 利用神经网络解决回归问题 4.2.1 问题介绍 4.2.2 利用pytorch解析数据 4.2.2 利用pytorch定义网络结构 4.2.3 开始训练 4.2.4 将模型进行保存 4.3 利用p…

云中马在A股上市:总市值约为40亿元,叶福忠为实际控制人

11月18日,浙江云中马股份有限公司(下称“云中马”,SH:603130)在上海证券交易所主板上市。本次上市,云中马的发行价为19.72元/股,发行数量为3500万股,募资总额约为6.90亿元,募资金额约…

码农必备?清华大学开源了一款写代码神器。。。

程序员宝藏库:https://gitee.com/sharetech_lee/CS-Books-Store 提升程序员编码效率,是一个经久不衰的话题,从最初用纯文本编辑器到后来代码自动补全,再到后来基于AI智能补全代码,开发者效率的确在不断提升。 关于新工…

这就是程序员眼中的函数吗?(一)

小叮当的任意门1. 函数是什么?2. C语言中的函数分类1. 库函数2. 自定义函数3. 函数的参数1. 实际参数(实参)2. 形式参数(形参)4. 函数的调用1. 传值调用2. 传址调用练习1. 写一个函数可以判断一个数是不是素数三级标题…

5分钟实现「视频检索」:基于内容理解,无需任何标签

Notebook 教程:text-video retrieval 「视频检索」任务就是输入一段文本,检索出最符合文本描述的视频。随着各类视频平台的兴起和火爆,网络上视频的数量呈现井喷式增长,「视频检索」成为人们高效查找视频的一项新需求。传统的视频…

Matlab点云处理及可视化第1期—基于KD树的邻域点搜索(柱状邻域、球状邻域及KNN)

目录 1 概述 2 代码实现 3 可视化验证 数据及完整代码获取方式: 观前提示:本文文字内容请勿直接用于论文写作,否则后果自负。 特别提示:《Matlab点云处理及可视化》系列文章旨在为初入点云处理领域的朋友提供一份较为权威、可…