【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事务 的相关文章

  • docker 非 root 绑定安装权限,WITH --userns-remap

    all 尝试让绑定安装权限正常工作 我的目标是在容器中绑定安装卷 以便 a 容器不以 root 用户身份运行入口点 二 docker daemon 配置了 userns remap 这样容器 主机上没有 root c 我可以绑定挂载和读 写
  • 在 .gitconfig 中隐藏 GitHub 令牌

    我想将所有点文件存储在 GitHub 上 包括 gitconfig 这需要我将 GitHub 令牌隐藏在 gitconfig 中 为此 我有一个 gitconfig hidden token 文件 这是我打算编辑并放在隐藏令牌的 git 下
  • 我们真的应该使用 Chef 来管理 sudoers 文件吗?

    这是我的问题 我担心如果 Chef 破坏了 sudoers 文件中的某些内容 可能是 Chef 用户错误地使用了说明书 那么服务器将完全无法访问 我讨厌我们完全失去客户的生产服务器 因为我们弄乱了 sudoers 文件并且无法再通过 ssh
  • tcpdump 是否受 iptables 过滤影响?

    如果我的开发机器有iptables规则到FORWARD一些数据包 这些数据包是否被 tcpdump 捕获 我有这个问题 因为我知道存在其他链称为INPUT如果数据包路由到 它会过滤发往应用程序的数据包FORWARD链 它会到达吗tcpdum
  • Linux 上的静态 Qt5 构建:部署时如何处理字体?

    我使用这些配置选项创建了 Qt 5 2 0 库的静态版本 Ubuntu 12 04 开源 确认许可 force pkg config 发布 静止的 前缀 home juzzlin qt5 无icu opengl桌面 无油嘴滑舌 辅助功能 n
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 使用 shell 脚本将行附加到 /etc/hosts 文件

    我有一个新的 Ubuntu 12 04 VPS 我正在尝试编写一个安装脚本来完成整个 LAMP 安装 我遇到问题的地方是在 etc hosts文件 我当前的主机文件如下所示 127 0 0 1 localhost Venus The fol
  • 在 Mono 上运行 .Net MVC5 应用程序

    我正在 Windows 上的 Visual Studio 2013 中开发 Net 4 5 1 MVC5 应用程序 现在我想知道 是否可以在Linux Ubuntu 12 04 上运行这个应用程序 可以使用OWIN吗 Owin 可以自托管运
  • 从 Xlib 转换为 xcb

    我目前正在将我的一个应用程序从 Xlib 移植到 libxcb 但在查找有关我有时使用的 XInput2 扩展的信息时遇到了一些麻烦 libxcb 中有 XInput2 实现吗 如果是的话 在哪里可以找到文档 目前我在使用此功能时遇到问题
  • 内核的panic()函数是否完全冻结所有其他进程?

    我想确认内核的panic 功能和其他类似kernel halt and machine halt 一旦触发 保证机器完全冻结 那么 所有的内核和用户进程都被冻结了吗 是panic 可以被调度程序中断吗 中断处理程序仍然可以执行吗 用例 如果
  • Flask-SocketIO redis 订阅

    我在用着https github com miguelgrinberg Flask SocketIO https github com miguelgrinberg Flask SocketIO实现 WebSocket 服务器 我需要从另一
  • 静态方法的 Java 内存模型

    我来自操作系统和 C 语言背景 在代码编译时 世界很简单 需要处理和理解堆栈 堆文本部分等 当我开始学习 Java 时 我确实了解 JVM 和垃圾收集器 我对静态方法感到很有趣 根据我的理解 类的所有实例都会在堆中创建 然后被清理 但是 对
  • Spring-boot中将redis-cache反序列化为对象的问题

    我在 Client 类中使用 JsonNode 来处理 MySQL 8 数据库中 JSON 类型的字段 即使对于 API 请求 它也能很好地工作 但是当我使用 Redis 启用缓存 我确实需要它 时 我注意到 Redis 无法序列化 Jso
  • 如何在Redis中存储聚合目录树搜索结果

    我有一个很大的产品目录树 目前包含约 36000 个类别和约 100 万个产品 即叶子 它的结构如下 最大深度为 5 Cat1 Cat11 Cat111 Cat1111 Product1 Cat1112 Product1 Cat1113 P
  • Intel 上的 gcc 中的 _mm_pause 用法

    我参考过这个网页 https software intel com en us articles benefitting power and performance sleep loops https software intel com
  • 在生产服务器上使用 Subversion 使文件生效的最佳方法是什么?

    目前我已经设置了 subversion 这样当我在 Eclipse PDT 中进行更改时 我可以提交更改 它们将保存在 home administrator 中项目文件 该文件具有 subversion 推荐的 branches tags
  • Linux/POSIX:为什么 fork() 不分叉*所有*线程

    众所周知 POSIX下创建新进程的默认方式是使用fork 在 Linux 下 这在内部映射到clone 我想知道的是 众所周知 当一个人打电话时fork 子进程是用单个线程创建的 调用的线程fork cf https linux die n
  • 检查已安装的软件包,如果没有找到则安装

    我需要检查已安装的软件包 如果未安装则安装它们 RHEL CentOS Fedora 示例 rpm qa grep glibc static glibc static 2 12 1 80 el6 3 5 i686 如何在 BASH 中进行检
  • 如何让 Node.js 作为后台进程运行并且永不死掉?

    我通过 putty SSH 连接到 linux 服务器 我尝试将其作为后台进程运行 如下所示 node server js 然而 2 5 小时后 终端变得不活动 进程终止 即使终端断开连接 我是否也可以使进程保持活动状态 Edit 1 事实
  • 尽管我已在 python ctypes 中设置了信号处理程序,但并未调用它

    我尝试过使用 sigaction 和 ctypes 设置信号处理程序 我知道它可以与python中的信号模块一起使用 但我想尝试学习 当我向该进程发送 SIGTERM 时 但它没有调用我设置的处理程序 只打印 终止 为什么它不调用处理程序

随机推荐

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

    接上篇 人脸关键点检测和头部姿态估计数据集整理 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