我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Redis事务基本指令有哪些

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Redis事务基本指令有哪些

本篇内容主要讲解“Redis事务基本指令有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Redis事务基本指令有哪些”吧!

Redis 事务简介

Redis 只是提供了简单的事务功能。其本质是一组命令的集合,事务支持一次执行多个命令,在事务执行过程中,会顺序执行队列中的命令,其他客户端提交的命令请求不会插入到本事务执行命令序列中。命令的执行过程是顺序执行的,但不能保证原子性。无法像 MySQL 那样,有隔离级别,出了问题之后还能回滚数据等高级操作。后面会详细分析。

Redis 事务基本指令

Redis 提供了如下几个事务相关的基础指令。

MULTI开启事务,Redis 会将后续命令加到队列中,而不真正执行它们,直到后续使用EXEC来原子化的顺序执行这些命令 EXEC执行所有事务块内的命令 DISCARD取消事务,放弃执行事务块内所有的命令 WATCH监视一个或多个 key,若事务在执行前,这些 key 被其他命令修改,则事务被终端,不会执行事务中的任何命令 UNWATCH取消 WATCH命令对所有 keys 的监视

一般情况下,一个简单的 Redis 事务主要分为如下几个部分:

执行命令MULTI开启一个事务。 开启事务之后,执行命令的多个命令会依次被放入一个队列,放入成功则会返回QUEUED消息。 执行命令EXEC提交事务,Redis 会依次执行队列中的命令,并依次返回所有命令的结果。(若想放弃提交事务,则执行DISCARD)。

下图简单介绍了下 Redis 事务执行的过程:

Redis事务基本指令有哪些

实例分析

下面我们来通过一些实际具体例子,来体会下 Redis 中的事务。前面我们也说到 Redis 的事务不是正真的事务,是无法完全满足标准事务的ACID特性的。通过下面的例子,我们来看看,Redis 的“破产版”事务到底存在什么问题。

[A]正常执行提交

127.0.0.1:6379> MULTIOK127.0.0.1:6379> SET a 1QUEUED127.0.0.1:6379> SET b 2QUEUED127.0.0.1:6379> EXEC1) OK2) OK127.0.0.1:6379> GET a"1"127.0.0.1:6379> GET b"2"

开启事务后,提交的命令都会加入队列(QUEUED),执行 EXEC 后会逐步执行命令并返回结果。这个看起来是不是和我们平时使用 MySQL 的事务操作相似,类似 start transaction 和 commit。

[B]正常取消事务

127.0.0.1:6379> MULTIOK127.0.0.1:6379> SET a 1QUEUED127.0.0.1:6379> SET b 2QUEUED127.0.0.1:6379> DISCARDOK127.0.0.1:6379> 127.0.0.1:6379> GET a(nil)127.0.0.1:6379> GET b(nil)

开启事务后,若不想继续事务,使用 DISCARD 取消,前面提交的命令并不会真正执行,相关的 key 值不变。这个看起来也和 MySQL 的事务相似,类似 start transaction 和 rollback。

[C]WATCH 监视 key

-- 线程 1 中执行127.0.0.1:6379> del a(integer) 1127.0.0.1:6379> get a(nil)127.0.0.1:6379> SET a 0OK127.0.0.1:6379> WATCH aOK127.0.0.1:6379> MULTIOK127.0.0.1:6379> SET a 1QUEUED----------------------------------------- 线程 2 中执行----------------------------------------- 127.0.0.1:6379> SET a 2----------------------------------------- OK127.0.0.1:6379> EXEC(nil)127.0.0.1:6379> GET a"2"

在开启事务之前 WATCH 了 a 的值,随后再开启事务。在另一个线程中设置了 a 的值(SET a 2),然后再 EXEC 执行事务,结果为 nil,
说明事务没有被执行。因为 a 的值在 WATCH 之后发生了变化,所以事务被取消了。

需要注意的是,这里和开启事务的时间点没有关系,与 MULTI 和另一个线程设置 a 的值的先后没有关系。只要是在 WATCH 之后发生了变化。无论事务是否已经开启,执行事务(EXEC)的时候都会取消。
普通情况下,在执行 EXEC 和 DISCARD 命令时,都会默认执行 UNWATCH。

[D]语法错误

127.0.0.1:6379> SET a 1OK127.0.0.1:6379> SET b 2OK127.0.0.1:6379> MULTIOK127.0.0.1:6379> SET a 11QUEUED127.0.0.1:6379> SETS b 22(error) ERR unknown command 'SETS'127.0.0.1:6379> EXEC(error) EXECABORT Transaction discarded because of previous errors.127.0.0.1:6379> GET a"1"127.0.0.1:6379> GET b"2"

当 Redis 开启一个事务后,若添加的命令中有语法错误,会导致事务提交失败。这种情况下事务队列中的命令都不会被执行。如上面例子中 a 和 b 的值都是原有的值。
这类在 EXEC 之前产生的错误,如命令名称错误,命令参数错误等,会在 EXEC 执行之前被检测出来,所以在发生这些错误的时候,事务会被取消,事务中的所有命令都不会执行。(这种情况看起来是不是有点像回滚了)

[E]运行时错误

127.0.0.1:6379> MULTIOK127.0.0.1:6379> SET a 1QUEUED127.0.0.1:6379> SET b helloQUEUED127.0.0.1:6379> INCR bQUEUED127.0.0.1:6379> EXEC1) OK2) OK3) (error) ERR value is not an integer or out of range127.0.0.1:6379> GET a"1"127.0.0.1:6379> GET b"hello"

当 Redis 开启一个事务后,添加的命令没有出现前面说的语法错误,但是在运行时检测到了类型错误,导致事务最提交失败(说未完全成功可能更准确点)。此时事务并不会回滚,而是跳过错误命令继续执行。
如上面的例子,未报错的命令值已经修改,a 被设置成了 1,b 被设置为了 hello,但是报错的值未被修改,即 INCR b 类型错误,并未执行,b 的值也没有被再更新。

Redis 事务与 ACID

通过上面的例子,我们已经知道 Redis 的事务和我们通常接触的 MySQL 等关系数据库的事务还有有一定差异的。它不保证原子性。同时 Redis 事务也没有事务隔离级别的概念。下面我们来具体看下 Redis 在 ACID 四个特性中,那些是满足的,那些是不满足的。
事务执行可以分为命令入队(EXEC 执行前)和命令实际执行(EXEC 执行之后)两个阶段。下面我们在分析的时候,很多时候都会分这两种情况来分析。

原子性(A)

上面的实例分析中,[A],[B],[C]三种正常的情况,我们可以很明显的看出,是保证了原子性的。
但是一些异常情况下,是不满足原子性的。

如 [D] 所示的情况,客户端发送的命令有语法错误,在命令入队列时 Redis 就判断出来了。等到执行 EXEC 命令时,Redis 就会拒绝执行所有提交的命令,返回事务失败的结果。此种情况下,事务中的所有命令都不会被执行了,是保证了原子性的。 如 [E] 所示的情况,事务操作入队时,命令和操作类型不匹配,此时 Redis 没有检查出错误(这类错误是运行时错误)。等到执行 EXEC 命令后,Redis 实际执行这些命令操作时,就会报错。需要注意的是,虽然 Redis 会对错误的命令报错不执行,但是其余正确的命令会依次执行完。此种情况下,是无法保证原子性的。 在执行事务的 EXEC 命令时,Redis 实例发生了故障,导致事务执行失败。此时,如果开启了 AOF 日志,那么只会有部分事务操作被记录到 AOF 日志中。使用redis-check-aof工具检测 AOF 日志文件,可以把未完成的事务操作从 AOF 文件中去除。这样一来,使用 AOF 文件恢复实例后,事务操作不会被再执行,从而保证了原子性。若使用的 RDB 模式,最新的 RDB 快照是在 EXEC 执行之前生成的,使用快照恢复之后,事务中的命令也都没有执行,从而保证了原子性。若 Redis 没有开启持久化,则重启后内存中的数据全部丢失,也就谈不上原子性了。 一致性(C)

一致性指的是事务执行前后,数据符合数据库的定义和要求。这点在 Redis 事务中是满足的,不论是发生语法错误还是运行时错误,错误的命令均不会被执行。

EXEC 执行之前,入队报错(实例分析中的语法错误)

事务会放弃执行,故可以保证一致性。

EXEC 执行之后,实际执行时报错(实例分析中的运行时错误)

错误的命令不会被执行,正确的命令被执行,一致性可以保证。

EXEC 执行时,实例宕机

若 Redis 没有开启持久化,实例宕机重启后,数据都没有了,数据是一致的。
若配置了 RDB 方式,RDB 快照不会在事务执行时执行。所以,若事务执行到一半,实例发生了故障,此时上一次 RDB 快照中不会包含事务所做的修改,而下一次 RDB 快照还没有执行,实例重启后,事务修改的数据会丢失,数据是一致的。若事务已经完成,但新一次的 RDB 快照还没有生成,那事务修改的数据也会丢失,数据也是一致的。
若配置了 AOF 方式。当事务操作还没被记录到 AOF 日志时,实例就发生故障了,使用 AOF 日志恢复后数据是一致的。若事务中的只有部分操作被记录到 AOF 日志,可以使用 redis-check-aof清除事务中已经完成的操作,数据库恢复后数据也是一致的。

隔离性(I) 并发操作在 EXEC 执行前,隔离性需要通过 WATCH 机制来保证 并发操作在 EXEC 命令之后,隔离性可以保证

情况 a 可以参考前面的实例分析 WATCH 命令的使用。
情况 b,由于 Redis 是单线程执行命令,EXEC 命令执行后,Redis 会保证先把事务队列中的所有命令执行完之后再执行之后的命令。

持久性(D)

若 Redis 没有开启持久化,那么就是所有数据都存储在内存中,一旦重启,数据就会丢失,因此此时事务的持久性是肯定无法得到保证的。
若 Redis 开启了持久化,当实例宕机重启,还是会有可能丢失数据,因此也并能完全保证持久性。
因此,我们可以说 Redis 事务无法一定保证持久性,仅在特殊的情况下,可以保证持久性。

关于 Redis 在开启持久化之后,为啥还会丢失数据,笔者会单独整理一篇 Redis 持久化与主从相关的文章来介绍,此处简单说下。
如果配置了 RDB 模式,在一个事务执行后,下一次 RDB 快照还未执行前,Redis 实例发生了宕机,数据就会丢失、
如果配置了 AOF 模式,而 AOF 模式的三种配置选项 no,everysec,always 也都可能会产生数据丢失的情况。

总结一下,Redis 事务对 ACID 的支持情况:

具备一定的原子性,但不支持回滚 满足一致性 满足隔离性 无法保证持久性 Redis 事务为什么不支持回滚

看一下官网的的说明:

What about rollbacks?
Redis does not support rollbacks of transactions since supporting rollbacks would have a significant impact on the simplicity and performance of Redis.

Redis事务基本指令有哪些

大部分需要事务回滚的情况是程序错误导致的,这种情况一般是开发环境,生产环境不应该出现这种错误。
对于逻辑错误,例如应该加 1,结果写成了加 2,这种情况无法通过回滚来解决。
Redis 追求的是简单高效,而传统事务的实现相对复杂很多,这和 Redis 的设计思想是违背的。当我们享受 Redis 的快速时,也就无法再要求它更多。

到此,相信大家对“Redis事务基本指令有哪些”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Redis事务基本指令有哪些

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Redis事务基本指令有哪些

本篇内容主要讲解“Redis事务基本指令有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Redis事务基本指令有哪些”吧!Redis 事务简介Redis 只是提供了简单的事务功能。其本质是一
2023-07-04

docker中有哪些基本的指令

这期内容当中小编将会给大家带来有关docker中有哪些基本的指令,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、查看当前机器的容器情况 通常情况下,我们可以使用docker ps命令来查看当前机器
2023-06-14

Vue中有哪些基本的指令

Vue中有哪些基本的指令?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。一. v-on指令1. 基础用法v-on是事件监听的指令, 下面来看简单用法
2023-06-06

Linux常用的文件基本指令有哪些

这篇文章主要介绍“Linux常用的文件基本指令有哪些”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Linux常用的文件基本指令有哪些”文章能帮助大家解决问题。帮助指令man man ls
2023-07-06

docker基本命令有哪些

这篇文章主要介绍了docker基本命令有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。docker基本命令docker文件系统docker镜像为分层设计,相比于全量的虚拟
2023-06-29

linux的基本命令有哪些

这篇文章将为大家详细讲解有关linux的基本命令有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一些常用的基本命令:uname -a查看内核版本ls -al显示所有文件的属性pwd 显示当前路径cd
2023-06-17

Docker的基本命令有哪些

小编给大家分享一下Docker的基本命令有哪些,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!一、系统相关命令:1.1 查看docker 的版本信息:docker version1.2 查看docker 系统信息:docke
2023-06-07

redis基本数据类型有哪些

redis基本数据类型有:1、String;2、List;3、Set;4、Hash;5、Sorted Set。详细介绍:1、String,这是Redis最基本的数据类型,可以存储任何类型的数据,包括字符串、数字和二进制数据等;2、List,
redis基本数据类型有哪些
2023-12-18

Helm常用基本命令有哪些

这篇文章主要介绍了Helm常用基本命令有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Helm 是 Kubernetes 的软件包管理工具。本文需要读者对 Docker、
2023-06-28

Vue事件的基本操作有哪些

小编给大家分享一下Vue事件的基本操作有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1. 事件的基本操作1.1 v-on功能:绑定指定事件名的回调函数标准写
2023-06-29

Oracle RAC基本维护命令有哪些

今天就跟大家聊聊有关Oracle RAC基本维护命令有哪些,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Oracle RAC日常基本维护命令所有实例和服务的状态$ srvctl st
2023-06-06

Git的基本操作命令有哪些

本篇内容主要讲解“Git的基本操作命令有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Git的基本操作命令有哪些”吧!Git 基本操作Git 的工作就是创建和保存你项目的快照及与之后的快照进
2023-06-17

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录