【征服redis2】redis的事务与lua

1.redis事务介绍

在前面我们介绍了redis的几种典型数据结构和应用,本文我们来看一下redis的事务问题。事务也是数据库的重要主题,熟悉关系型数据库的读者应该对事务比较了解,简单地说,事务表示一组动作,要么全部执行,要么全部不执行。例如在社交网站上用户 A关注了用户B,那么需要在用户A的关注表中加入用户B,并且在用户B的粉丝表中添加用户A,这两个行为要么全部执行,要么全部不执行,否则会出现数据不一致的情况。

Redis提供了简单的事务功能,将一组需要一起执行的命令放到 multi和exec两个命令之间。multi命令代表事务开始,exec命令代表事务 结束,它们之间的命令是原子顺序执行的,例如下面操作实现了上述用户关注问题。

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> sadd user:a:follow user:b
QUEUED
127.0.0.1:6379(TX)> sadd user:b:fans user:a
QUEUED

可以看到sadd命令此时的返回结果是QUEUED,代表命令并没有真 正执行,而是暂时保存在Redis中。如果此时另一个客户端执行 sismember user:a:follow user:b返回结果应该为0。

127.0.0.1:6379> sismember user:a:follow user:b
(integer) 0

只有当exec执行后,用户A关注用户B的行为才算完成,如下所示返回的两个结果对应sadd命令。

第一个终端:
127.0.0.1:6379(TX)> exec
1) (integer) 1
2) (integer) 1第二个终端:
127.0.0.1:6379> sismember user:a:follow user:b
(integer) 1

如果要停止事务的执行,可以使用discard命令代替exec命令即可。

2 事务出错的处理

如果事务中的命令出现错误,Redis的处理机制也不一样。

情况1.命令错误

例如下面操作错将set写成了sett,属于语法错误,会造成整个事务无法执行,key和counter的值未发生变化。

比如说我们按照下面的方式来执行redis事务:

127.0.0.1:6379> mget key counter

1) "2"

2) "100"

127.0.0.1:6379> 

127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> sett key world

(error) ERR unknown command `sett`, with args beginning with: `key`, `world`, 

127.0.0.1:6379(TX)> incr counter

QUEUED

127.0.0.1:6379(TX)> exec

(error) EXECABORT Transaction discarded because of previous errors.

127.0.0.1:6379> mget key counter

1) "2"

2) "100"

127.0.0.1:6379> 

可以看到最后的counter并没有发生变化。

情况2.运行时错误

例如用户B在添加粉丝列表时,误把sadd命令写成了zadd命令,这种就是运行时命令,因为语法是正确的,redis是无法察觉到这种错误的。例如:

127.0.0.1:6379> multi

OK

127.0.0.1:6379(TX)> sadd user:a:follow user:b

QUEUED

127.0.0.1:6379(TX)> zadd user:b:fans 1 user:a

QUEUED

127.0.0.1:6379(TX)> exec

1) (integer) 0

2) (error) WRONGTYPE Operation against a key holding the wrong kind of value

127.0.0.1:6379> sismember user:a:follow user:b

(integer) 1

127.0.0.1:6379> 

可以看到Redis并不支持回滚功能,sadd user:a:follow user:b命令已经执行成功,开发人员需要自己修复这类问题。

有些应用场景需要在事务之前,确保事务中的key没有被其他客户 端修改过,才执行事务,否则不执行(类似乐观锁)。Redis提供了watch命令来解决这类问题,下表展示了添加watch之后两个客户端执行命令的时序。

可以看到“客户端-1”在执行multi之前执行了watch命令,“客户 端-2”在“客户端-1”执行exec之前修改了key值,造成事务没有执行(exec 结果为nil),整个代码如下所示:

客户端1:

127.0.0.1:6379> set key "java"

OK

127.0.0.1:6379> watch key

OK

127.0.0.1:6379> multi

OK

此时客户端2执行:

append key python

然后回到客户端1:

127.0.0.1:6379(TX)> append key jedis

QUEUED

127.0.0.1:6379(TX)> exec

(nil)

127.0.0.1:6379> get key

"javapython"

127.0.0.1:6379>

Redis提供了简单的事务,之所以说它简单,主要是因为它不支持 事务中的回滚特性,同时无法实现命令之间的逻辑关系计算,当然也体现了Redis的“keep it simple”的特性,下一小节介绍的Lua脚本同样可以实现事务的相关功能,但是功能要强大很多。

lua的问题,我们后面再介绍。

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

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

相关文章

Python 实现快速排序的代码

使用 Python 实现快速排序的代码&#xff1a; python def quicksort(arr): if len(arr) < 1: return arr pivot arr[len(arr) // 2] left [x for x in arr if x < pivot] middle [x for x in arr if x pivot] right [x for x in arr if x > pivot] retu…

esp32-idf Eclipse Log日志打印demo

Log日志打印demo 1、代码例程 esp32-S2 芯片 / Eclipse软件 开发环境 #include <stdio.h> #include "sdkconfig.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "esp_system.h" #include "esp_…

【linux】终端发送网络请求与文件下载

发送网络请求 linux的终端中发送网络请求可以使用curl命令。 语法&#xff1a; curl [url] 但是他返回的是html代码&#xff0c;因为在终端中&#xff0c;他无法像浏览器中一样把访问到的html代码渲染成我们访问的页面&#xff0c;所以我们只能拿到他的源码。 访问CSDN - 专…

1.机器学习-机器学习算法分类概述

机器学习-机器学习算法分类概述 个人简介机器学习算法分类&#xff1a;监督学习、无监督学习、强化学习一监督学习1. 监督学习分类任务举例&#xff1a;1.1 特征1.2 标签 二无监督学习1.关键特点2.应用示例3.常见的无监督学习算法 三强化学习1.定义2.示例场景 四机器学习开发流…

数据结构之串|数组|广义表

串 数组 广义表 总结&#xff1a;

2021-05-31 git操作

Git 多人协作开发的过程 Git可以完成两件事情&#xff1a; 版本控制 2.多人协作开发 如今的项目&#xff0c;规模越来越大&#xff0c;功能越来越多&#xff0c;需要有一个团队进行开发。 如果有多个开发人员共同开发一个项目&#xff0c;如何进行协作的呢。 Git提供了一个…

【加强版】小学数学出题,加减乘除混合运算,支持自定义数字,一键打印

在线预览&#xff1a;在线HTML代码预览和运行工具 - UU在线工具 复制下面代码后到该地址预览即可 注意&#xff1a;在线预览不能打印。如需打印&#xff0c;在电脑本地上新建文本文档&#xff0c;粘贴代码后保存&#xff0c;然后把文件后缀改为.html运行&#xff0c;出题点击…

haiku实现三角乘法模块

三角乘法&#xff08;TriangleMultiplication&#xff09;是作为一种更对称、更便宜的三角注意力&#xff08;TriangleAttention&#xff09;替代模块。 import jax import haiku import jax.numpy as jnpdef _layer_norm(axis-1, namelayer_norm):return common_modules.Laye…

【CF闯关练习】—— 1400分(C. Make Good、B. Applejack and Storages)

&#x1f30f;博客主页&#xff1a;PH_modest的博客主页 &#x1f6a9;当前专栏&#xff1a;cf闯关练习 &#x1f48c;其他专栏&#xff1a; &#x1f534;每日一题 &#x1f7e1; C跬步积累 &#x1f7e2; C语言跬步积累 &#x1f308;座右铭&#xff1a;广积粮&#xff0c;缓…

isis小实验

要求: 1.合理规划level1-2 2.r1访问r5走r6且走上面 3.全网可达 个人理解:以重发布的视角:is-level level1即L1可以看做rip,L2可以看做OSPF,L1-2可以看作是既要rip又要OSPF,优点:isis只用在每个路由器上宣告一次 缺点:isis需要每个接口上输isis enable 1(序号)特点:L1-2会自动下…

vue流程图

效果图 组件 <template><div class="processBox" v-if="list.length"><div class="childs"><div class="child" v-for="(item,index) in list" :key="item.id +-child-+index"><div…

C++中的指针、引用和数组

参考文档&#xff1a;《21天学通C&#xff08;第8版&#xff09;》 C中对于指针、引用和数组使用时&#xff0c;充斥着 * 、& 、[]符号&#xff0c;对于像我这样的初学者面对这些符号难免会陷入混乱。 当然&#xff0c;C中对符号 * 、& 、[] 赋予了多重意义也是让人容易…

C //练习 6-5 编写函数undef,它将从由lookup和install维护的表中删除一个变量及其定义。

C程序设计语言 &#xff08;第二版&#xff09; 练习 6-5 练习 6-5 编写函数undef&#xff0c;它将从由lookup和install维护的表中删除一个变量及其定义。 注意&#xff1a;代码在win32控制台运行&#xff0c;在不同的IDE环境下&#xff0c;有部分可能需要变更。 IDE工具&am…

Java http 响应式请求和非响应式请求有什么区别

在Java中&#xff0c;HTTP的响应式请求和非响应式请求有以下区别&#xff1a; HTTP协议本身并不直接支持响应式请求&#xff0c;因为HTTP是基于请求-响应模型的。然而&#xff0c;可以通过使用其他技术和协议来实现响应式请求。 响应方式&#xff1a;响应式请求是指使用响应式编…

SpringBoot 调用错:getWriter() has already been called for this response

这个错误通常表明您尝试从Spring MVC返回一个已使用的HttpServletResponse对象。 原因&#xff1a;这可能是由于直接调用HttpServletResponse的getWriter()或getOutputStream()方法&#xff0c;或者由于在控制器方法中抛出异常而自动调用HttpServletResponse的write()方法。 修…

第10章_多线程扩展练习(Thread类中的方法,线程创建,线程通信)

文章目录 第10章_多线程扩展练习Thread类中的方法1、新年倒计时 线程创建2、奇偶数输出3、强行加塞4、奇偶数打印5、龟兔赛跑友谊赛6、龟兔赛跑冠军赛7、多人过山洞8、奇偶数连续打印9、字母连续打印 线程通信10、奇偶数交替打印11、银行账户-112、银行账户-2 第10章_多线程扩展…

协方差矩阵自适应调整的进化策略(CMA-ES)

关于CMA-ES&#xff0c;其中 CMA 为协方差矩阵自适应(Covariance Matrix Adaptation)&#xff0c;而进化策略&#xff08;Evolution strategies, ES&#xff09;是一种无梯度随机优化算法。CMA-ES 是一种随机或随机化方法&#xff0c;用于非线性、非凸函数的实参数&#xff08;…

SparkSQL——DataFrame

DataFrame Dataframe 是什么 DataFrame 是 SparkSQL中一个表示关系型数据库中 表的函数式抽象, 其作用是让 Spark处理大规模结构化数据的时候更加容易. 一般 DataFrame可以处理结构化的数据, 或者是半结构化的数据, 因为这两类数据中都可以获取到 Schema信息. 也就是说 DataFra…

数据结构之tuple类

前言 tuple 是元组类。tuple 就很有意思了&#xff0c;它和上一篇文章介绍的list 十分相似&#xff0c;都是线性表。最大的不同就是list 可以改变&#xff0c;而tuple 是不可变的。元组就像是列表的补充&#xff0c;我们甚至可以这么理解&#xff1a;元组就是只读的列表。 1.…

自动驾驶模拟器

目录 Carla 自动驾驶模拟器 Udacity自动驾驶模拟器 Carla 自动驾驶模拟器 pip install carla 需要下载地图 Udacity自动驾驶模拟器