【Redis入门】-浅谈redis事务

2023-11-13

说到事务大家都不陌生,在关系型数据库中,事务时并发控制的基本单位,他是一个操作的序列,可以包含多个指令,并且,对于一个事务,其内部的指令要么全部执行,要么都不执行,内部指令不可分割。

关系型数据库的事务具有四个特性:

1. 原子性

2. 一致性

3. 隔离性

4. 持久性

而在我们redis数据库中,事务回事什么样子的呢?

首先我们给出一个定义:redis的事务中,一次执行多条命令,本质是一组命令的集合,一个事务中所有的命令将被序列化,即按顺序执行而不会被其他命令插入

在redis中,事务的作用就是在一个队列中一次性、顺序性、排他性的执行一系列的命令。

事务的生命周期:

1. 事务的创建:使用MULTI开启一个事务

2. 加入队列:在开启事务的时候,每次操作的命令将会被插入到一个队列中,同时这个命令并不会被真的执行

3. EXEC命令进行提交事务

常用的关于事务的命令有:

1. MULTI:使用该命令,标记一个事务块的开始,通常在执行之后会回复OK,(但不一定真的OK),这个时候用户可以输入多个操作来代替逐条操作,redis会将这些操作放入队列中。

2. EXEC:执行这个事务内的所有命令

3. DISCARD:放弃事务,即该事务内的所有命令都将取消

4. WATCH:监控一个或者多个key,如果这些key在提交事务(EXEC)之前被其他用户修改过,那么事务将执行失败,需要重新获取最新数据重头操作(类似于乐观锁)。

5. UNWATCH:取消WATCH命令对多有key的监控,所有监控锁将会被取消。

注意:关于乐观锁等概念:

   乐观锁:就像他的名字,不会认为数据不会出错,他不会为数据上锁,但是为了保证数据的一致性,他会在每条记录的后面添加一个标记(类似于版本号),假设A 获取K1这条标记,得到了k1的版本号是1,并对其进行修改,这个时候B也获取了k1这个数据,当然,B获取的版本号也是1,同样也对k1进行修改,这个时候,如果B先提交了,那么k1的版本号将会改变成2,这个时候,如果A提交数据,他会发现自己的版本号与最新的版本号不一致,这个时候A的提交将不会成功,A的做法是重新获取最新的k1的数据,重复修改数据、提交数据。

  悲观锁:这个模式将认定数据一定会出错,所以她的做法是将整张表锁起来,这样会有很强的一致性,但是同时会有极低的并发性(常用语数据库备份工作,类似于表锁)。

那么,现在我们来执行一次具体看看redis的事务机制:

首先我会开启事务,并向数据库中存储4条数据,可以看到没执行一条命令的时候都会显示入队,并不会返回执行结果,说明redis中在事务提交之前,其内部的所有命令将不会被执行:

那么,如果中间有命令出错了会怎样呢?现在我随便打几个字符试一试:

可以看出,在第三条命令中我随便打了几个字符,提交事务的时候并没有成功,这也很符合我们对事务的理解,嗯~具有原子性。但是,有一个细节,那就是错误命令在我输入的时候就已经报错了,也就是说这个条错误命令在进入队列的时候redis就已经知道这是一条错误命令,这样,整个事务的命令将全部失败,那么,有没有一种可能某个错误指令在进入队列的时候redis还没有发现他的错误呢?我们试一试下面这个例子:

问题出现了,我们可以看到,name+1这条指令其实是错误的,但是提交事务的时候会发现,这条错误命令确实没有执行,但是其他正确的命令却执行,这是为什么的?

原因是在redis中,对于一个存在问题的命令,如果在入队的时候就已经出错,整个事务内的命令将都不会被执行(其后续的命令依然可以入队),如果这个错误命令在入队的时候并没有报错,而是在执行的时候出错了,那么redis默认跳过这个命令执行后续命令。也就是说,redis只实现了部分事务。

下面我们来看看刚刚提到的锁的问题,我们说过,redis的锁CAS(check and set)类似于乐观锁,redis的实现原理是使用watch进行监视一个(或多个)数据,如果在事务提交之前数据发生了变化(估计使用了类似于乐观锁的标记),那么整个事务将提交失败,我们可以举一个例子,我们开启两个终端,模拟两个人的操作,设置一条数据为count,初始时100,现在A对其进行监控,并且为count增加20

在没有提交之前,B也获取了这个count,为其减少50,

那么这个时候A如果提交事务,会出现失败提示:

可以看到,在A对数据的修改过程中,B对数据进行了修改,那么这条数据的“标记”就发生了变化,已经不是当初A取出数据的时候的标记了,这样,A的事务也就提交失败了。

最后通过上述的实验,我们总结redis事务的三条性质:

1. 单独的隔离操作:事务中的所有命令会被序列化、按顺序执行,在执行的过程中不会被其他客户端发送来的命令打断
2. 没有隔离级别的概念:队列中的命令在事务没有被提交之前不会被实际执行
3. 不保证原子性:redis中的一个事务中如果存在命令执行失败,那么其他命令依然会被执行,没有回滚机制

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Redis入门】-浅谈redis事务 的相关文章

  • 在 Linux 上访问 main 之外的主要参数

    是否可以访问参数main在外面main 即在共享库构造函数中 在 Linux 上除了通过解析之外 proc self cmdline 您可以通过将构造函数放入 init array部分 功能在 init array 不像 init 使用相同
  • pprof 和 ps 之间的内存使用差异

    我一直在尝试分析用 cobra 构建的 cli 工具的堆使用情况 这pprof工具显示如下 Flat Flat Sum Cum Cum Name Inlined 1 58GB 49 98 49 98 1 58GB 49 98 os Read
  • 推荐用于小型站点的 IRC 服务器 (ircd)? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 情况 我想使用 IRC 机器人作为我正在研究的其他代码的通用通信接口 服务器硬件陈旧且内存不足 但运行在相对最新的 Debian GNU
  • 这种 bash 文件名提取技术有何用途?

    我有一部分 bash 脚本正在获取不带扩展名的文件名 但我试图了解这里到底发生了什么 是做什么用的 有人可以详细说明 bash 在幕后做了什么吗 如何在一般基础上使用该技术 bin bash for src in tif do txt sr
  • 从 Python 访问 802.11 无线管理帧

    我想从 Linux 上的 Python 嗅探 802 11 管理 探测请求 帧 这可以从 Scapy 中实现 如下所示 coding utf 8 from scapy all import def proc p if p haslayer
  • 如何使用redis发布/订阅

    目前我正在使用node js和redis来构建应用程序 我使用redis的原因是因为发布 订阅功能 该应用程序只是在用户进入用户或离开房间时通知经理 function publishMsg channel mssage redisClien
  • 如何重命名 .tar.gz 文件而不提取内容并在 UBUNTU 中创建新的 .tar.gz 文件?

    我有一个命令将创建一个新的 tar gz现有文件中的文件 sudo tar zcvf Existing tar gz New tar gz 该命令将创建一个新的New tar gz从现有的文件Existing tar gz file 谁能告
  • 将node.js +expressjs应用程序的NODE_ENV设置为ubuntu下的守护进程

    我按照这些说明让守护进程正常工作 http kevin vanzonneveld net techblog article run nodejs as a service on ubuntu karmic http kevin vanzon
  • 使用c在linux上分块读写

    我有一个 ASCII 文件 其中每一行都包含一个可变长度的记录 例如 Record 1 15 characters Record 2 200 characters Record 3 500 characters Record n X cha
  • 在 Linux 控制台中返回一行?

    我知道我可以返回该行并用以下内容覆盖其内容 r 现在我怎样才能进入上一行来改变它呢 或者有没有办法打印到控制台窗口中的特定光标位置 我的目标是使用 PHP 创建一些自刷新的多行控制台应用程序 Use ANSI 转义码 http en wik
  • 在非实时操作系统/内核上执行接近实时任务的最佳方法是什么?

    在一台 GNU Linux 机器上 如果想要执行 实时 亚毫秒级时间关键 任务 您几乎总是必须经历漫长 复杂且容易出现问题的内核补丁过程 以提供足够的支持 1 http en wikipedia org wiki RTLinux Backg
  • 如何将 elf 解释器(ld-linux.so.2/ld-2.17.so)构建为静态库?

    如果我的问题不准确 我深表歉意 因为我没有太多 Linux 相关经验 我目前正在构建一个 Linux 从头开始 主要遵循 linuxfromscratch org 版本的指南 7 3 我遇到了以下问题 当我构建可执行文件时 获取一个称为 E
  • 为什么默认情况下不启用 arp 忽略/通告 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一个需要经验才能回答的具体问题 为什么 arp ignore arp announce 在 Linux 安装 例如 debian 上默认不启用 有
  • 比较linux中的两个未排序列表,列出第二个文件中的唯一项

    我有 2 个包含号码列表 电话号码 的文件 我正在寻找一种列出第二个文件中第一个文件中不存在的数字的方法 我尝试过各种方法 comm getting some weird sorting errors fgrep v x f second
  • 了解 Linux oom-killer 日志

    我的应用程序被 oom killer 杀死了 它是在实时 USB 上运行的 Ubuntu 11 10 无需交换 PC 具有 1 Gig 的 RAM 唯一运行的应用程序 除了所有内置的 Ubuntu 东西 是我的程序 flasherav 请注
  • Spring Data Redis 覆盖默认序列化器

    我正在尝试创建一个RedisTemplatebean 将具有更新的值序列化器来序列化对象JSONredis 中的格式 Configuration class RedisConfig Bean name redisTemplate Prima
  • Laravel Redis 配置

    我目前正在使用 Laravel 和 Redis 创建一个应用程序 几乎一切都工作正常 我按照文档中的说明扩展了身份验证 用户可以订阅 登录 注销 我可以创建内容 所有内容都存储在 Redis 中 但我有一个问题 我无法运行 php arti
  • 为什么 call_usermodehelper 大多数时候都会失败?

    从内核模块中 我尝试使用 call usermodehelper 函数来执行可执行文件 sha1 该可执行文件将文件作为参数并将文件的 SHA1 哈希和写入另一个文件 名为输出 可执行文件完美运行 int result 1 name hom
  • Apache LOG:子进程 pid xxxx 退出信号分段错误 (11)

    Apache PHP Mysql Linux 注意 子进程 pid 23145 退出信号分段错误 11 tmp 中可能存在 coredump 但 tmp下没有找到任何东西 我怎样才能找到错误 PHP 代码中函数的无限循环导致了此错误
  • 如何回忆上一个 bash 命令的参数?

    Bash 有没有办法回忆上一个命令的参数 我通常这样做vi file c其次是gcc file c Bash 有没有办法回忆上一个命令的参数 您可以使用 or 调用上一个命令的最后一个参数 Also Alt can be used to r

随机推荐

  • 人脸关键点检测和头部姿态估计数据集生成

    接上篇 人脸关键点检测和头部姿态估计数据集整理 1 借助于OpenPose生成人脸关键点和头部姿态 使用链接 https github com TadasBaltrusaitis OpenFace wiki Command line arg
  • 小白都能看懂 XAMPP的下载安装配置详细教程(含拒绝访问坑)

    话不相瞒 当初为了在XAMPP Apache MySQL PHP PERL 里面配置phpwind 我在卸载与安装之间来回了不下10次 但是我的phpwind始终还是安装不成功 我可能是招坑体质 真的很无奈 最终 我放弃了phpwind 废
  • openmv串口打包发送数据

    openmv端 import time from pyb import UART import ustruct uart UART 3 19200 uart init 19200 8 None 1 def send data d globa
  • hadoop搭建及常见问题

    这是本人在完全分布式环境下在Cent OS中配置Hadoop 0 20 203 0时的总结文档 但该文档也适合其他版本的Linux系统和目前各版本的Hadoop Hadoop 0 20之后的版本配置文件hadoop site xml被拆分成
  • 使用Python,OpenCV对图像进行亚像素点检测,并拟合椭圆进行绘制

    这篇博客将介绍如何使用Python OpenCV对图像进行亚像素检测 并对亚像素点进行椭圆拟合绘制 1 效果图 原始图上绘制拟合椭圆 VS 原始图上绘制拟合椭圆及亚像素点绘制随机半径及颜色的圆 VS 灰度图上绘制亚像素点效果图如下 我喜欢的
  • 安装 mysqlclient==1.3.12 报错:OSError: mysql_config not found

    安装 mysqlclient 1 3 12 报错 OSError mysql config not found Collecting mysqlclient 1 3 12 Using cached mysqlclient 1 3 12 ta
  • 【Mo 人工智能技术博客】时间序列预测——DA-RNN模型

    时间序列预测 DA RNN模型 作者 梅昊铭 1 背景介绍 传统的用于时间序列预测的非线性自回归模型 NRAX 很难捕捉到一段较长的时间内的数据间的时间相关性并选择相应的驱动数据来进行预测 本文将介绍一种基于 Seq2Seq 模型 Enco
  • 在centos7安装anaconda3操作手册

    一 Anaconda下载 进入anaconda官方网站下载个人免费版本 网站链接 点击download 选择Linux平台的安装包 二 Anaconda安装 1 执行如下指令 安装anaconda 进入当保存文件的目录 执行此指令 后期由于
  • Jina AI‘2021

    2022 农历新年进入倒数阶段 回望 2021 因为有了社区和开发者们的支持和助力 Jina AI 从产品 社区 到用户案例及团队 都取得了一些相当哇塞的成就 接下来 我们就一起来重温一下 2021 年 Jina AI 的惊喜变化 领取 J
  • 第十一天栈与队列

    20 有效的括号 力扣题目链接 opens new window 给定一个只包括 的字符串 判断字符串是否有效 有效字符串需满足 左括号必须用相同类型的右括号闭合 左括号必须以正确的顺序闭合 注意空字符串可被认为是有效字符串 题外话 括号匹
  • opencv项目实践一(答题卡识别)

    答题卡素材图片 思路 读入图片 做一些预处理工作 进行轮廓检测 然后找到该图片最大的轮廓 就是答题卡部分 进行透视变换 以去除除答题卡外的多于部分 并且可以对答题卡进行校正 再次检测轮廓 定位每个选项 对选项圆圈先按照竖坐标排序 再按照行坐
  • 十进制有符号小数转换成二进制数的实现_Matlab实现_归一化处理

    在一些数据处理过程中 需要将一组十进制小数转换成二进制数存储或者计算 这种操作在FPGA的使用中会经常遇到 本文分析了十进制小数转换成二进制数的方法 1 N位二进制数的取值范围 N位无符号型 unsigned 取值范围 2 N 1 0 可以
  • Java中守护线程的总结 thread.setDaemon(true)

    https www cnblogs com ziq711 p 8228255 html 在Java中有两类线程 User Thread 用户线程 Daemon Thread 守护线程 用个比较通俗的比如 任何一个守护线程都是整个JVM中所有
  • 服务器windows系统数据盘不显示不出来,解决云主机没有显示数据盘的问题

    随着网络的发展 越来越多的站长与企业都在使用云主机 但是目前由于云主机的尚未成熟 所有大家在使用过程中经常会遇到使用方面的问题 下面我们总结了下有关云主机重装或者初建时数据盘不见的问题做了解说 希望对大家有所帮助 经常会有用户询问 我们的云
  • R语言KERAS深度学习CNN卷积神经网络分类识别手写数字图像数据(MNIST)

    最近我们被客户要求撰写关于卷积神经网络的研究报告 包括一些图形和统计输出 在本文中 我们将学习如何使用keras 用手写数字图像数据集 即MNIST 进行深度学习 本文的目的是为了让大家亲身体验并熟悉培训课程中的神经网络部分 1 软件包的下
  • Vue-cli安装文档及使用(搭建vue-cli、nodejs、webpack架子)

    之前学习基础语法 todolist 所有的代码写在index html之中 大型项目不可维护 在真实vue项目开发过程中 会借助webpack打包工具帮助构建大型项目开发目录 再开发完成之后进行打包的操作 帮助生成线上可运行的代码 如果让每
  • 树莓派教程 - 1.5 树莓派GPIO库wiringPi 使用硬件串口ttyAMA0与ttyS0

    Git例程源码仓库 https github com ZhiliangMa raspberry git 上一篇介绍 ttyS0串口的用法 说到了此串口利弊 可能会出现乱码 但绝对能满足绝大部分的要求 本节使用 dev ttyAMA0 的方法
  • CentOS7 安装配置FTP服务器的问题

    C C 气象数据中心实战工业级项目系列 第三章 CentOS7 安装配置FTP服务器的问题 文章目录 C C 气象数据中心实战工业级项目系列 一 参考 二 设置 data ftp ftpuser upload目录 代表着只能在这个目录中上传
  • mysql in和exists性能比较和使用

    in 是把外表和内表作hash 连接 而exists是对外表作loop循环 每次loop循环再对内表进行查询 一直以来认为exists比in效率高的说法是不准确的 如果查询的两个表大小相当 那么用in和exists差别不大 如果两个表中一个
  • 【Redis入门】-浅谈redis事务

    说到事务大家都不陌生 在关系型数据库中 事务时并发控制的基本单位 他是一个操作的序列 可以包含多个指令 并且 对于一个事务 其内部的指令要么全部执行 要么都不执行 内部指令不可分割 关系型数据库的事务具有四个特性 1 原子性 2 一致性 3