Redis:事务操作

news2024/11/19 2:38:33

目录

  • Redis事务定义
  • 相关命令
  • 事务的错误处
  • 事务冲突的问题
  • Redis事务三特性

Redis事务定义

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

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

相关命令

主要有Multi、Exec、discard。

  1. multi

标记一个事务块的开始。

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

  1. exec

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

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

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

  1. discard

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

从输入Multi命令开始,输入的命令都会依次进入命令队列中,但不会执行,直到输入Exec后,redis会将之前的命令依次执行。组队的过程中可以通过discard来放弃组队。

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

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

在这里插入图片描述

示例:

# 示例1:事务被成功执行
redis> MULTI 
OK
redis> INCR user_id
QUEUED 
redis> INCR user_id 
QUEUED 
redis> INCR user_id 
QUEUED 
redis> PING 
QUEUED
redis> EXEC 
1) (integer) 1 
2) (integer) 2 
3) (integer) 3 
4) PONG

# 示例2:监视 key,且事务成功执行 
redis> WATCH lock lock_times 
OK
redis> MULTI
OK
redis> SET lock "huangz" 
QUEUED 
redis> INCR lock_times 
QUEUED 
redis> EXEC 
1) OK 
2) (integer) 1

# 示例3:监视 key,且事务被打断 
redis> WATCH lock lock_times 
OK
redis> MULTI
OK
redis> SET lock "joe" # 就在这时,另一个客户端修改了 lock_times 的值 
QUEUED 
redis> INCR lock_times 
QUEUED 
redis> EXEC # 因为 lock_times 被修改, joe 的事务执行失败 
(nil)

# 示例3:取消事务
redis> MULTI 
OK
redis> PING
QUEUED 
redis> SET greeting "hello"
QUEUED 
redis> DISCARD
OK

事务的错误处

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

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

在这里插入图片描述

示例代码如下,事务中执行了3个set命令,而第3个命令 set address 命令本身有问题,加入队列失败,最后执行exec的时候,所有的命令都被取消执行。

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.
  1. 情况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对应的值被其他命令所改动了,那么事务中所有命令都将被打断,即事务所有操作将被取消执行。

示例:

开启2个窗口,按照下表的时间点在不同的窗口执行对应的命令

在这里插入图片描述

窗口1中,对balance进行了监视,也就是说在执行 watch balance 命令之后,在 exec 命令之前,如果有其他请求对balance进行了修改,那么窗口1事务中所有的命令都会将会被取消执行。窗口1 watch balance 后,由于T5时刻窗口2对balance进行了修改,导致窗口1中事务所有命令被取消执行。

unwatch:取消监视

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

如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行UNWATCH 了。因为 EXEC 命令会执行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同时也会取消所有对 key 的监视,因此这两个命令执行之后,就没有必要执行 UNWATCH 了。

Redis事务三特性

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

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

不能保证原子性:事务中如果有一条命令执行失败,后续的命令仍然会被执行,没有回滚。如果在组队阶段,有1个失败了,后面都不会成功;如果在组队阶段成功了,在执行阶段有那个命令失败就这条失败,其他的命令则正常执行,不保证都成功或都失败。

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

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

相关文章

车载电子电器架构 ——电子电气架构设计方案概述

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 注:本文1万多字,认证码字,认真看!!! 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证…

作为Java初学者,如何快速学好Java?

作为Java初学者,如何快速学好Java? 开始的一些话 对于初学者来说,编程的学习曲线可能相对陡峭。这是正常现象,不要感到沮丧。逐步学习,循序渐进。 编程是一门实践性的技能,多写代码是提高的唯一途径。尽量…

【一起来学kubernetes】7、k8s中的ingress详解

引言配置示例负载均衡的实现负载均衡策略实现模式实现方案Nginx类型Ingress实现Treafik类型Ingress实现HAProxy类型ingress实现Istio类型ingress实现APISIX类型ingress实现 更多 引言 Ingress是Kubernetes集群中的一种资源类型,用于实现用域名的方式访问Kubernetes…

[图片来源BZhan]最小生成树(Prim➕Kruskal)、最短路径(Dijkstra➕Floyd)

文章目录 0.基础知识0.1图的存储结构0.2算法复杂度1.BFS和DFS2.Prim和Kruskal 1.最小生成树1.1Prim算法1.算法思想2.Prim代码实现 1.2Kruskal算法1.算法思想2.Kruskal代码实现[demo] 2.最短路径2.1问题抽象:2.2两种常见的最短路径问题:1.Dijkstra: 单源最短路径O(N^2)2.Floyd: …

停车管理系统

1 用户信息管理 2 车位信息管理 3 车位费用设置 4 停泊车辆查询 5 车辆进出管理 6 用户个人中心 7 预定停车位 8 缴费信息 9 业务逻辑详解 1 用户停车:user用户登录,在预定停车位菜单,选择一个车位点击预定即可 2 车辆驶出:admin…

【数据结构实验】图(二)将邻接矩阵存储转换为邻接表存储

文章目录 1. 引言2. 邻接表表示图的原理2.1 有向权图2.2 无向权图2.3 无向非权图2.1 有向非权图 3. 实验内容3.1 实验题目(一)数据结构要求(二)输入要求(三)输出要求 3.2 算法实现 4. 实验结果 1. 引言 图是…

电磁场信息论及先进MIMO (黄大年茶思屋座谈) 笔记

天线阵的负载动态调控,动态阻抗匹配网络,实时跟着扫描角度的变化而变化,可能突破Hannan极限。 新的天线构架: 周期 —》非周期 每个单元不一样 动态可调,可重构 每个天线多端口或多模式 多层天线 非周期结构天线的增…

paho mqtt的keepAliveInterval

一、keepAliveInterval 所用的版本为1.3.12 实验一、 这个值设置的30,打开mqtt的trace,发现每隔33s发送一次pingreq note: 期间,client和server一直保持qos0的消息交互(client->server) 实验二、 …

Python武器库开发-前端篇之CSS元素(三十二)

前端篇之CSS元素(三十二) CSS 元素是一个网页中的 HTML 元素,包括标签、类和 ID。它们可以通过 CSS 选择器选中并设置样式属性,以使网页呈现具有吸引力和良好的可读性。常见的 HTML 元素包括 div、p、h1、h2、span 等,它们可以使用 CSS 设置…

1panel可视化Docker面板安装与使用

官网地址1Panel - 现代化、开源的 Linux 服务器运维管理面板 文章目录 目录 文章目录 前言 一、环境准备 二、使用步骤 1.安装命令 2.一些命令 3.使用 总结 前言 一、环境准备 虚拟机centos 已经安装好docker和 Docker Compose 或者都没安装 1panel会帮你自动安装 二、使用…

原生javascript实现放大镜效果

效果图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>放大镜</title><style&g…

YOLOv5改进 | 添加SE注意力机制 + 更换NMS之EIoU-NMS

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。为提高算法模型在不同环境下的目标识别准确率&#xff0c;提出一种基于改进 YOLOv5 深度学习的识别方法&#xff08;SE-NMS-YOLOv5&#xff09;&#xff0c;该方法融合SE&#xff08;Squeeze-and-Excitation&#xff09;注…

​root账号登录群晖NAS教程​

用WinSCPPuTTY以root账号登录群晖NAS保姆教程用WinSCPPuTTY可SecureCRT 以root账号登录群晖NAS 1、先用自己的用户名 密码登陆。 2、切换到root权限 输入sudo -i,按回车,然后也是输入群辉登录的密码。成功之后,显示$ 变成 #号

module java.base does not “opens java.io“ to unnamed module

环境 如上图所示&#xff0c; Runtime version的版本是JAVA 17 项目所需要JDK版本为JAVA 8 解决

【差旅游记】走进新疆哈密博物馆

哈喽&#xff0c;大家好&#xff0c;我是雷工&#xff01; 前些天在新疆哈密时&#xff0c;有天下午有点时间&#xff0c;看离住的宾馆不远就是哈密博物馆&#xff0c;便去逛了逛博物馆&#xff0c;由于接下来的一段时间没顾上记录&#xff0c;趁今天有些时间简单记录下那短暂的…

Robots 元标签与 X-Robots 标签

Robots Meta Tag 和 X-Robots-Tag 是两个常用的 HTML 标签&#xff0c;它们对观察机动爬虫和其他网络机器人很有启发性。这些标签可以控制您的网页如何被记录和显示。 什么是机器人元标记&#xff1f; 机器人元标记是一个 HTML 标签&#xff0c;它提供信息来查看电机爬虫和其…

【C++那些事儿】类与对象(3)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;我之前看过一套书叫做《明朝那些事儿》&#xff0c;把本来枯燥的历史讲的生动有趣。而C作为一门接近底层的语言&#xff0c;无疑是抽象且难度颇…

Java学习路径:入门学习、深入学习、核心技术,操作案例和实际代码示例

学习路径&#xff1a;入门学习、深入学习、核心技术&#xff0c; 每个主题都包括很多的操作案例和实际代码示例。 a. 入门学习&#xff1a; 1. 基础语法&#xff1a; 变量和数据类型&#xff1a; // 定义和初始化变量 int age 25;// 不同数据类型的声明 double price 19.99…

⑥【bitmap 】Redis数据类型: bitmap [使用手册]

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ Redis bitmap ⑥Redis bitmap 基本操作命令1. …

node.js解决输出中文乱码问题

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;九黎aj &#x1f3c3;&#x1f3fb;‍♂️幸福源自奋斗,平凡造就不凡 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f331;欢迎订阅我的…