Redis:事务操作

目录

  • 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个失败了,后面都不会成功;如果在组队阶段成功了,在执行阶段有那个命令失败就这条失败,其他的命令则正常执行,不保证都成功或都失败。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

HTAP 还可以这么玩?丨TiDB 在 IoT 智慧园区的应用

作者:某物联网公司设施云平台负责人 用户简介:我们是一家提供全链智慧园区整体解决方案的物联网公司,致力于打造可持续发展的智慧园区。 基础设施平台简介 基础设施平台是集团一线作业人员日常工作中高度依赖的重要系统,涵盖了各…

涉密计算机违规外联原因及防范措施

高度信息化的时代,涉密计算机违规外联已成为一种严重的安全威胁。涉密计算机违规外联是指涉密计算机通过互联网、电子邮件等方式与外部计算机或网络进行连接,导致机密信息泄露或被恶意攻击。 为了应对这一问题,本文将探讨涉密计算机违规外联的…

WPF实战项目十九(客户端):修改RestSharp的引用

修改HttpRestClient,更新RestSharp到110.2.0,因为106版本和110版本的代码不一样,所以需要修改下代码 using Newtonsoft.Json; using RestSharp; using System; using System.Threading.Tasks; using WPFProjectShared;namespace WPFProject.S…

wps备份功能 救了我一命

感谢wps备份功能 救了我一命 文章目录 感谢wps备份功能 救了我一命**📝场景回现,往后再不干了**🧣灵光一现📇备注中心的设置流程🖊️最后总结 📝场景回现,往后再不干了 小🐮今天接到…

理解BatchNormalization层的作用

深度学习 文章目录 深度学习前言一、“Internal Covariate Shift”问题二、BatchNorm的本质思想三、训练阶段如何做BatchNorm四、BatchNorm的推理(Inference)过程五、BatchNorm的好处六、机器学习中mini-batch和batch有什么区别 前言 Batch Normalization作为最近一年来DL的重…

Spring Task

1 介绍 Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。 定位:定时任务框架 作用:定时自动执行某段Java代码 为什么要在Java程序中使用Spring Task? 应用场景: 1). 信用卡…

MyBatis-Plus动态表名使用selectPage方法不生效问题解析与解决

文章目录 MyBatis-Plus动态表名简介selectPage方法不生效的问题解决方案:SqlParser注解与BaseMapper的selectPage方法示例代码实体类Mapper接口Service层Controller层 总结 🎉MyBatis-Plus动态表名使用selectPage方法不生效问题解析与解决 ☆* o(≧▽≦)…

【每日OJ —— 144. 二叉树的前序遍历】

每日OJ —— 144. 二叉树的前序遍历 1.题目:144. 二叉树的前序遍历2.方法讲解2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目:144. 二叉树的前序遍历 2.方法讲解 2.1.算法讲解 1.首先如果在每次每个节点遍历的时候都去为数组开辟空间,这样…

linux基础五:linux 系统(进程状态2:)

linux 系统 一.进程状态:1.睡眠状态(sleep):2.磁盘休眠状态(disk sleep):3.停止状态(stoped --- T):4.死亡状态:5.控制状态(t) 二.僵尸进程和孤儿进程:1.僵尸状态:2.孤儿…

同城服务足浴按摩软件系统开发方案;

足浴按摩软件是一款线上系统小程序,旨在方便用户在线预约按摩师、选择适合自己的服务项目和时间,并在家中或指定地点享受按摩服务。这款上门按摩小程序为用户提供了便利和个性化的按摩服务体验。 用户可以通过手机随时随地通过足浴按摩软件预约按摩师&am…

【java】编译时bug 项目启动前bug合集

文章目录 1. jdk8中 Optional orElseThrow 编译时报错java: 未报告的异常错误X; 必须对其进行捕获或声明以便抛出2. 启动项目时提示 Error running Application: Command line is too long. Shorten command line for Application or also for Spring Boot default configurati…

【每日OJ —— KY11 二叉树遍历】

每日OJ —— KY11 二叉树遍历 1.题目:KY11 二叉树遍历2.解法2.1.算法讲解2.2.代码实现2.3.提交通过展示 1.题目:KY11 二叉树遍历 2.解法 2.1.算法讲解 1.首先需要创建二叉树结构。 2.其次,根据题目根据题目遍历的顺序要求来实现构建二叉树的…

基于mps的pytorch 多实例并行推理

背景 大模型训练好后,进行部署时,发现可使用的显卡容量远大于模型占用空间 。是否可以同时加载多个模型实例到显存空间,且能实现多个实例同时并发执行?本次实验测试基于mps的方案,当请求依次过来时,多个相…

【分布式事务】Seata 开源的分布式事务解决方案

1. 什么是seata Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。 2. seata发展历程 阿里巴巴作为国内最早一批进行应用分…

使用 CSS Grid 的响应式网页设计:消除媒体查询过载

文章目录 前言介绍 CSS Grid让我们开始吧实现高级响应性1、Repeat() 2、Auto-fit3、Minmax()结论 前言 你是否厌倦了在实现响应式网站时需要管理多个媒体查询?说再见复杂的代码,拥抱更简单的解决方案吧:CSS Grid。 在这篇文章中,…

AI时代架构师之路:技术、洞察和创新的完美融合

随着人工智能技术的飞速发展,我们正置身于一个由数据驱动的时代。在这个充满无限可能性的AI时代,架构师成为设计和构建先进系统的关键角色。然而,在追逐技术的同时,架构师需要修炼一系列综合素养,使其在技术、业务和伦…

苍穹外卖——删除购物车信息

1. 删除购物车中一个商品 1.1 产品原型 1.2 接口设计 1.3 数据模型 shopping_cart表: -- auto-generated definition create table shopping_cart (id bigint auto_increment comment 主键primary key,name varchar(32) null comment 商品名称…

Jmeter接口自动化测试断言之Json断言

json断言可以让我们很快的定位到响应数据中的某一字段,当然前提是响应数据是json格式的,所以如果响应数据为json格式的话,使用json断言还是相当方便的。 还是以之前的接口举例 Url: https://data.cma.cn/weatherGis/web/weather/weatherFcst…

【LeetCode】 160. 相交链表

相交链表 题目题解 题目 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整个链式结构中不存在环。 注意&am…

python实现决策树可视化Graphviz和plot_tree

文章目录 效果展示graphviz安装教程实例演示数据集介绍属性说明划分训练集、测试集graphviz可视化plot_tree效果展示 graphviz安装教程 实例演示 数据集介绍 Wine葡萄酒数据集是来自UCI上面的公开数据集,这些数据是对意大利同一地区种植的葡萄酒进行化学分析的结果,这些葡…