Redis事务

news2024/9/22 7:09:59

Redis事务官网:
http://redis.cn/topics/transactions.html

一、Redis事务的特性

Redis事务可以一次执行多个命令,并且满足以下两个重要的特性

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

事务中的错误
使用事务时可能会遇上以下两种错误:

  • 事务在执行 EXEC 之前,入队的命令可能会出错。比如说,命令可能会产生语法错误(参数数量错误,参数名错误,等等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)
  • 命令可能在 EXEC 调用之后失败。举个例子,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面,诸如此类。

对于发生在 EXEC 执行之前的错误,客户端以前的做法是检查命令入队所得的返回值:如果命令入队时返回 QUEUED ,那么入队成功;否则,就是入队失败。如果有命令在入队时失败,那么大部分客户端都会停止并取消这个事务

至于那些在 EXEC 命令执行之后所产生的错误, 并没有对它们进行特别处理: 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。

【举例:当命令在入队时产生错误】当命令在入队时产生错误
在这里插入图片描述

【举例:exec之后命令执行错误】以下例子中, LPOP 命令的执行将出错, 尽管调用它的语法是正确的:
在这里插入图片描述
EXEC 返回两条bulk-string-reply: 第一条是 OK ,而第二条是 -ERR 。 至于怎样用合适的方法来表示事务中的错误, 则是由客户端自己决定的。
最重要的是记住这样一条,== 即使事务中有某条/某些命令执行失败了, 事务队列中的其他命令仍然会继续执行 —— Redis 不会停止执行事务中的命令==。

二、Redis事务四个命令 + 用法

MULTI 命令用于开启一个事务,它总是返回 OK 。 MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC命令被调用时, 所有队列中的命令才会被执行。

通过调用 DISCARD , 客户端可以清空事务队列, 并放弃执行事务

EXEC 命令的回复是一个数组, 数组中的每个元素都是执行事务中的命令所产生的回复。 其中, 回复元素的先后顺序和命令发送的先后顺序一致。

当客户端处于事务状态时, 所有传入的命令都会返回一个内容为 QUEUED 的状态回复, 这些被入队的命令将在 EXEC 命令被调用时执行。

三、WATCH命令的使用

  • WATCH使得EXEC命令有条件的执行,事务只能在所有被监视键都没有被修改的前提下执行,如果这个条件不满足的话,事务就不会执行

  • WATCH命令可以被调用多次,对键的监视从WATCH执行之后开始生效,直到调用EXEC为止

  • 用户还可以在单个WATCH命令中监视多个键,就像这样
    在这里插入图片描述

  • 当EXEC被调用时,不管事务是否执行成功,对所有键的监视都会取消;
    当客户端断开连接时,该客户端对键的监视也会取消;
    使用无参数的 UNWATCH 命令可以手动取消对所有键的监视。对于一些需要改动多个键的事务,有时候程序需要对多个键进行加锁,然后检查这些键的当前值是否符合程序的要求。当达不到要求时,就可以使用UNWATCH命令来取消目前对所有键的监视,中途放弃这个事务,等待下次执行

    使用WATCH 实现check-and-set 乐观锁

    WATCH命令可以为Redis事务提供 CAS行为
    被WATCH的键会被监视,并会发觉这些键是否被改动过了。如果至少一个被监视的键在EXEC执行之前被修改,那么整个事务会被取消,EXEC返回 nil-reply 表示事务已经失败

【举例】假设我们需要原子性地为某个值进行增 1 操作(假设 INCR 不存在)
首先我们可能会这样做:

val = GET mykey
val = val + 1
SET mykey $val

上面的这个实现在只有一个客户端的时候可以执行得很好。 但是, 当多个客户端同时对同一个键进行这样的操作时, 就会产生竞争条件。举个例子, 如果客户端 A 和 B 都读取了键原来的值, 比如 10 , 那么两个客户端都会将键的值设为 11 , 但正确的结果应该是 12 才对。
有了 WATCH , 我们就可以轻松地解决这类问题了:

WATCH mykey
val = GET mykey
val = val + 1
MULTI
SET mykey $val
EXEC

使用上面的代码, 如果在 WATCH 执行之后, EXEC 执行之前, 有其他客户端修改了 mykey 的值, 那么当前客户端的事务就会失败。 程序需要做的, 就是不断重试这个操作, 直到没有发生碰撞为止。

四、为什么 Redis 不支持回滚(roll back)

如果你有使用关系式数据库的经验, 那么 “Redis 在事务失败时不进行回滚,而是继续执行余下的命令”这种做法可能会让你觉得有点奇怪。

以下是这种做法的优点:

  • Redis 命令只会因为错误的语法而失败(并且这些问题不能在入队时发现),或是命令用在了错误类型的键上面:这也就是说,从实用性的角度来说,失败的命令是由编程错误造成的,而这些错误应该在开发的过程中被发现,而不应该出现在生产环境中
  • 因为不需要对回滚进行支持,所以 Redis 的内部可以保持简单且快速。

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

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

相关文章

CSS3 calc()函数

CSS3 calc()函数 概述 在CSS3中,我们可以使用calc()函数通过“计算”的方式来定义某一个属性的取值。 使用 语法 属性: calc(表达式);说明 可以使用calc()函数计算元素的width、margin、padding、font-size等。 对于calc()函数,有以下5条运算规则…

我的第一个基于vue-cli的程序

文章目录一 准备环境1.1 node.js安装1.2 安装Vue工具(Vue CLI)第一种安装方式【可能会遇到失败,如果失败请尝试第二种方式】下载的文件的存放位置第二种安装方式安装cnpm二 操作步骤2.0 进行目标文件夹下的命令行窗口2.1 创建项目2.2 成功2.3 运行项目2.4 效果一 准…

力扣1700.无法吃午餐的学生数量

题目描述: 学校的自助午餐提供圆形和方形的三明治,分别用数字 0 和 1 表示。所有学生站在一个队列里,每个学生要么喜欢圆形的要么喜欢方形的。 餐厅里三明治的数量与学生的数量相同。所有三明治都放在一个 栈 里,每一轮&#xff…

戴尔成就300015电脑出现错误代码怎么重新安装系统?

戴尔成就300015电脑出现错误代码怎么重新安装系统?有用户使用这款戴尔成就300015电脑的时候,总是在使用过程中无故的冒出错误代码,导致系统崩溃了。那么这个情况怎么去进行问题的修复呢?一起来看看详细的解决方法分享吧。 准备工作…

【深度学习】如何封装可维护的restiful api

这篇文章是用一个案例的形式尝试解决字段入参多了,在python这种风格的语言下如何维护的问题! 文章目录前言1. json 是个好东西2. json 是个坏东西3. json维护数据的适用范围总结4.解决4.1 基础版4.2 进阶版4.2.1 行动4.2.2 精进4.3 另一种选择总结前言 …

立根铸魂 崛起数智时代 GBASE受邀出席操作系统产业峰会2022

2022年12月28日,由openEuler开源社区发起举办的操作系统产业峰会2022/openEuler Summit 2022正式召开。GBASE荣幸受邀参加统信软件“深耕数字化”主题论坛,分享GBase 8c基于鲲鹏生态的创新实践历程和经验。 操作系统产业峰会2022 -南大通用GBase 8c基于鲲…

使用Nordic的nrf52832控制指定从机(一主多从)

一主多从1. 想要实现的功能2. 从机3. 主机3.1 主从机连接个数设置3.2 扫描过滤3.3 连接和断开连接3.4 按键处理3.5 从机读写3.5.1 写3.5.1 读4运行效果1. 想要实现的功能 1.主机能连接多个从机(主机作为控制器,从机作为节点)。 2.主机能使用…

Java跨域问题

目录 1、跨域问题说明 ​2、跨域解决方案 2.1、局部跨域解决方案 2.1.1、CrossOrigin注解跨域 2.1.2、手动设置响应头 2.2、全局跨域解决方案 2.2.1、实现WebMvcConfigurer接口设置跨域 2.2.2、定义CorsFilter Bean实现跨域 2.2.3、重写ResponseBodyAdvice接口中的bef…

ros的launch文件知识

_node标签: 在指定机器上启动节点respawn"true|false"(可选) 如果节点退出,是否自动重启respawndelay"N"(可选) 如果 respawn 为 true,那么延迟N秒后启动节点required"true|false"(可选) 该节点是否必须,如果…

ZooKeeper 避坑实践:SnapCount 设置不合理导致磁盘爆满,服务不可用

作者:子葵 背景 在 ZooKeeper 的日常使用过程中,一个令人头疼的问题就是节点的磁盘容量问题,如果由于过大的 TPS 或者不适当的清理策略会导致集群中数据文件,日志文件的堆积,最终导致磁盘爆满,Server 宕机…

在线客服系统部署配置邮箱消息通知功能 - 唯一客服(v1kf.com) -开源私有化独立部署在线客服系统源码...

为在线客服系统设置邮件通知具有以下几个好处: 改善客户体验:邮件通知可以让客户实时收到新消息或更新通知,这有助于提高他们对您的服务的整体体验。 提高效率:邮件通知可以帮助提高客服团队的效率,因为它们会在新消息…

非专业人士如何完成数据采集?纯干货,一文看懂

写在前面: 本教程能够解决大部分人的数据采集及分析需求,实用、简单,尤其适合Excel大户、办公族、业务人员,或者不会编程、不懂数据分析理论的技术小白…… 来不及看的可以先点赞收藏! 01 点对点的采集:…

吴恩达《机器学习》——欠拟合与过拟合

欠拟合与过拟合1. 方差与偏差模型的容量、过拟合和欠拟合2. Python代码实践2.1 拟合直线2.2 拟合多项式数据集、源文件可以在Github项目中获得 链接: https://github.com/Raymond-Yang-2001/AndrewNg-Machine-Learing-Homework 1. 方差与偏差 在数学上,估计的偏差…

Java基础漏洞(二)

继续填补自己的知识漏洞 1.&、&&、|、||之间的区别 &是逻辑与,而&&则是短路与。&和&&之间的区别是,在短路与&&的情况下,两个条件当第一个条件为假时,则不再执行第二个条件&#xf…

java学习之类方法

目录 一、基本介绍 二、类方法的调用 三、类方法的应用实例 代码 内存分析 运行结果 四、类方法的经典使用场景 五、类方法使用细节 第一条 第二条 第三条 第四条 第五条 第六条 六、练习 第一题 考察点 分析 结果 第二题 代码 考察点 结果 第三题 类方法 …

LeetCode498. 对角线遍历

LeetCode刷题记录 文章目录📜题目描述💡解题思路⌨C代码📜题目描述 给你一个大小为 m x n 的矩阵 mat ,请以对角线遍历的顺序,用一个数组返回这个矩阵中的所有元素。 示例1 输入:mat [[1,2,3],[4,5,6],[…

VUE2使用浏览器缓存的方法

分两种:localStorage和sessionStorage,它两统称webStorage 注意点1:localStorage对象和sessionStorage对象都是window对象下的,且方法都是一样的,默认”window.”可以省略,添加可用setItem(K,V),查询可用ge…

数据库|scMethBank:单细胞全基因组 DNA 甲基化图谱数据库

甲基化是DNA的一种重要化学修饰,可调节基因的表达和关闭,与癌症、衰老、老年痴呆等许多疾病密切相关,是表观遗传学的重要研究内容之一。测序技术的发展,极大促进了单细胞DNA甲基化研究。然而大量数据的不断积累,对单细…

《HTTP权威指南》----HTTP报文

目录 报文流 报文的组成部分 报文语法 1.起始行 2.首部 通用首部,既可以出现在请求报文中也可以出现在响应报文中。 请求首部,提供更多有关请求的信息。 响应首部,提供更多有关响应的信息。 实体首部,描述主题的长度和内…

2022年,一个技术账号的年终独白,满篇都写着2个字:真难。

2022年,梦想橡皮擦这个账号经历了成长,突破,回归 2023年,适应改变 文章目录序2022年,梦想橡皮擦账号整体汇总原创博客KPI计划与完成总排名KPI计划与完成2022年,橡皮擦获得的荣誉2022年,做技术博…