2023.1.19 关于 Redis 事务详解

目录

Redis 事务对比 MySQL 事务

MySQL 事务

Redis 事务

Redis 事务原子性解释

Redis 事务详解

执行流程

典型使用场景

Redis 事务命令

WATCH 的使用

WATCH 实现原理

总结


阅读下文之前建议点击下方链接了解 MySQL 事务详解

MySQL 事务详解


Redis 事务对比 MySQL 事务

MySQL 事务

  • 原子性:将多个操作打包成一个整体,要么全部执行成功,要么全部都不执行,一旦执行出错,立刻回滚如初
  • 一致性:事务执行前后,通过约束和回滚机制,保证数据合理
  • 持久性:事务做出的修改会存储到硬盘上,不会随着服务器重启而丢失
  • 隔离性:事务并发执行,涉及 四大隔离级别

Redis 事务

  • 原子性:Redis 的事务到底有没有原子性 存在争议
  • 不具备一致性:Redis 没有约束,也没有回滚机制,事务操作过程中如果某个修改操作出现失败,就可能引起不一致的情况
  • 不具备持久性:Redis 本身就是内存数据库,数据是存储在内存中的,虽然 Redis 也有持久化机制,但是这里的持久化机制 和 事务没有啥直接关系
  • 不涉及隔离性:Redis 是一个单线程模型的服务器程序,所有的请求 或 事务都是串行执行的

Redis 事务原子性解释

  • 原子性最原本的含义:将多个操作打包到一起,要么全部执行,要么全部不执行
  • Redis 和 MySQL 均做到了原子性最原本的含义

注意:

  • Redis 仅能保证 多个操作全部一起执行或者不执行,但是不保证是否能够执行成功!
  • 即如果事务中若干个操作,存在有失败执行失败的操作,不会进行回滚!!
  • 但是 MySQL 面对上述情况会进行回滚操作,以保证事务的 一致性!

小总结:

  • MySQL 提高了原子性的门槛
  • 这就使得人们谈到原子性的时候,更多的是想到的 MySQL 这种带有回滚机制的原子性
  • 所以 Redis 事务是否具有原子性便存在这样的歧义
  • Redis 事务有原子性:可将多个操作能够打包到一起执行
  • Redis 事务不具有原子性:可将多个操作能够打包到一起执行,但是不具有回滚机制,无法保证这多个操作能够正确的执行

Redis 事务详解

  • Redis 事务的主要意义就是为了打包 ,以便避免其他客户端的命令插队到中间

  • Redis 引入队列来实现事务,该队列 每个客户端均有一个

执行流程

  • 开启事务
  • 客户端输入命令,命令发给服务器并且插入到队列中,此时的命令不会立即执行
  • 输入 执行事务 命令,队列中的命令 按照顺序依次执行
  • 依次执行的过程,均由 Redis 主线程完成,主线程会把事务中的操作执行完,再去执行其他客户端的命令

问题:

  • Redis 事务为什么这么简单,为啥不设计成和 MySQL 事务一样强大呢?

回答:

  • MySQL 事务在实现上付出了很大的代价
  • 空间上:花费更多的空间来存储更多的数据
  • 时间上:有着更大的执行开销
  • 也正是因为 MySQL 上述的代价,才有了 Redis 上场的机会

典型使用场景

  • 关于超卖问题
  • 一款商品放货 5000 台,如果有 5001 个人下单成功,这便属于超卖

典型写法:

  • 如果不加上任何限制,便可能存在 线程安全 问题
  • 在多线程中,均通过加锁的方式,来避免 插队

Redis 事务写法:

  • Redis 本身就是一个单线程模型,所以其天然不具有线程安全问题
  • 所以此处我们直接使用 Redis 事务,将购买商品所需进行的流程打包到一起执行即可

注意:

  • Redis 服务器只有收到 执行事务 命令的时候 才会真正执行 事务队列中的命令 !

具体理解:

  • 只有客户端B 的 执行事务 命令发过来之后,服务器才会真正执行客户端B 的事务队列
  • 与此同时 客户端A 的事务队列已经执行完成
  • 则 客户端B 事务队列中 get 到的 count 就已经是 客户端A 事务队列执行完之后的结果
  • 即采用 Redis 事务方法 无需加锁也能解决上述超卖问题

小总结:

  • Redis 事务的应用场景没有 MySQL 事务那么多
  • Redis 如果是按照集群模式部署的,则不支持事务

问题:

  • Redis 命令中能进行条件判定吗?

回答:

  • Redis 原生命令中确实没有像 if 这种的条件判定
  • 但是 Redis 支持 lua 脚本
  • 通过 lua 脚本便可以实现上述实例那样的条件判定,并且和事务一样,也是打包批量执行
  • lua 脚本的实现方式是 Redis 事务的进阶版本

Redis 事务命令

MULTI     开启事务
exec      执行事务
discard   放弃当前事务
watch     监控某个 key 是否在事务执行之前发送变化
unwatch   放弃监控

实例理解

  • 此处演示正确执行一个 Redis 事务

  • 此处演示放弃执行一个 Redis 事务


问题:

  • 开启事务,给服务器发送若干个命令后,此时服务器重启,那么该事务将会如何呢?

回答:

  • 上述场景的效果就等同于 discard


WATCH 的使用

  • watch 命令用于监控某个 key 是否在事务执行之前,发生了改变

实例理解

  • 从时间上来看,客户端A 先发送 set key 222,客户端B 后发送 set key 333
  • 但是由于 客户端A ,只有执行了 exec 命令,才会真正执行 set key 222 命令
  • 即 exec 命令 比 客户端B 的 set key 333 命令后执行
  • 所以上图中,key 的最终值为 222

注意:

  • 上述场景便可使用 watch 命令来监控这个 key
  • 看看这个 key 在事务 MULTI 和 exec 之间,是否被 外部其他客户端修改


WATCH 实现原理

  • watch 的实现 类似于一个 乐观锁
  • Redis 的 watch 命令相当于基于 版本号 这样的机制来进行实现的乐观锁

  • 这样的设定 在 CAS 这里 ABA 问题中也涉及过 思想方法 还是 实现上都是非常相似的

总结

  • Redis 事务,要比 MySQL 事务要简单很多
  1. 原子性:Redis 事务,不支持回滚
  2. 一致性:Redis 并不会保证事务执行前和执行后,数据统一
  3. 持久性:Redis 主要通过内存来存储数据
  4. 隔离性:Redis 自身作为一个单线程的服务器模型,上面处理的请求本质上都是串行执行的

  • Redis 中的 lua 脚本,也能起到类似于事务的效果
  • 官方网站上,事务这里的任何能实现的效果,都可以使用 lua 脚本代替

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

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

相关文章

hadoop-common: CMake failed with error code 1

问题 在编译hadoop源码时遇到如下错误 hadoop-common: CMake failed with error code 1 看了这个错误表示一脸懵逼 排查 在mvn 的命令中增加 -X 和 -e mvn clean package -e -X -Pdist,native -DskipTests -Dmaven.javadoc.skip -Dopenssl.prefix/usr/local/bin/openssl 在…

【1】SM4 CBC-MAC 机制

0x01 题目 MSG1: e55e3e24a3ae7797808fdca05a16ac15eb5fa2e6185c23a814a35ba32b4637c2 MAC1: 0712c867aa6ec7c1bb2b66312367b2c8 ----------------------------------------------------- MSG2: d8d94f33797e1f41cab9217793b2d0f02b93d46c2ead104dce4bfec453767719 MAC2: 4366…

助力焊接场景下自动化缺陷检测识别,基于YOLOv3模型开发构建工业焊接场景下缺陷检测识别分析系统

焊接是一个不陌生但是对于开发来说相对小众的场景,在我们前面的博文开发实践中也有一些相关的实践,感兴趣的话可以自行移步阅读即可: 《轻量级模型YOLOv5-Lite基于自己的数据集【焊接质量检测】从零构建模型超详细教程》 《基于DeepLabV3Pl…

Elasticsearch 分布式架构剖析及扩展性优化

1. 背景 Elasticsearch 是一个实时的分布式搜索分析引擎,简称 ES。一个集群由多个节点组成,节点的角色可以根据用户的使用场景自由配置,集群可以以节点为单位自由扩缩容,数据以索引、分片的形式散列在各个节点上。本文介绍 ES 分布…

阿里云ECS使用docke搭建redis服务

目录 1.确保正确安装好docker 2.安装redis镜像 3.创建容器设置端口映射 1.确保正确安装好docker 安装教程: 阿里云ECS(CentOS镜像)安装docker-CSDN博客https://blog.csdn.net/qq_62262918/article/details/135686614?spm1001.2014.3001.5501 2.安装redis镜像…

音乐人声分离工具:极简的人声和背景音乐分离工具

项目地址:jianchang512/vocal-separate: an extremely simple tool for separating vocals and background music, completely localized for web operation, using 2stems/4stems/5stems models 这是一个极简的人声和背景音乐分离工具,本地化网页操作&a…

appium连接手机进行启动失败 ,怎么办 ?检查下这几个地方 。

在使用appium做app自动化,首先需要启动appium连接到手机,然后进行后续操作。 但是往往在启动的时候就会卡住,在点击start session后就会出现报错,具体如下图 : 那么,出现如上的情况该如何解决呢 &#xff1…

计算机安全学习笔记(V):UDP和网络扫描

User Datagram Protocol (UDP) UDP是最简单的传输协议。多个程序(服务)可以在主机上侦听,因此操作系统需要知道将流量发送到哪个程序。 在传输协议中,每个程序都与源和目标处的端口相关联,该端口显示为程序的套接字。…

设计社交网络的数据结构

1: 确定 Use Case 和 约束 Use Cases User 搜索某人然后看到被搜索人的最短路径Service 有高可用 约束和假设 状态假设 Traffic 不是平均分布的 一些被搜索者是更加受欢迎的,某些被搜索者只会被搜索一次图数据不适用与单个机器图的分布是轻量级的一亿个 User每…

JavaScript 学习笔记(WEB APIs Day2)

「写在前面」 本文为 b 站黑马程序员 pink 老师 JavaScript 教程的学习笔记。本着自己学习、分享他人的态度,分享学习笔记,希望能对大家有所帮助。推荐先按顺序阅读往期内容: 1. JavaScript 学习笔记(Day1) 2. JavaSc…

c++QT文件IO

1、QFileDialog文件对话框 与QMessageBox一样,QFileDialog也继承了QDialog类,直接使用静态成员函数弹窗。弹出的结果(选择文件的路径)通过返回值获取。 1)获取一个打开或保存的文件路径 // 获取一个打开或保存的文件路…

插入排序(一)——直接插入排序与希尔排序

目录 一.前言 二.排序的概念及其运用 1.1排序的概念 1.2 常用排序算法 三.常用排序算法的实现 3.1 插入排序 3.1.1 基本思想 3.1.2 直接插入排序 3.1.3 希尔排序(缩小增量排序) 四.全部代码 sort.c sort.h test.c 五.结语 一.前言 本文我们…