【Redis 进阶】事务

Redis 的事务和 MySQL 的事务概念上是类似的,都是把一系列操作绑定成一组,让这一组能够批量执行。


一、Redis 的事务和 MySQL 事务的区别

1、MySQL 事务

  • 原子性:把多个操作打包成一个整体。(要么全都做,要么都不做)
  • ⼀致性:事务执行前和执行后,数据得保持相同
  • 隔离性:事务并发执行涉及到的一些问题(脏读、幻读等)。
  • 持久性:事务中做出的修改都会存储到硬盘中。

2、Redis 的事务

  • 弱化的原子性:redis 没有 “回滚机制”,只能做到这些操作 “批量执行”,不能做到 “一个失败就恢复到初始状态”,也就是无法保证执行成功。(网上有的说 Redis 事务有原子性(只是打包一起执行),有的说没有原子性(打包一起执行 + 带有回滚 —— 打包一起正确执行))
  • 不保证⼀致性:不涉及 “约束”,也没有回滚(MySQL 的一致性体现的是运行事务前和运行后,结果都是合理有效的,不会出现中间非法状态)。事务在执行过程中如果某个修改操作出现失败,就可能引起不一致的情况。
  • 不需要隔离性:也没有隔离级别,因为不会并发执行事务(Redis 是一个单线程模型的服务器程序,所有的请求 / 事务都是 “串行” 执行的)。
  • 不需要持久性:Redis 本身就是内存数据库,数据是存储在内存中的。虽然 Redis 也有持久化机制,但是否开启持久化是 redis-server 自己的事情,和事务无关。

Redis 事务本质上是在服务器上搞了⼀个 “事务队列”,每次客户端在事务中进行一个操作,都会把命令先发给服务器,放到 “事务队列” 中,但并不会立即执行,而是在收到 EXEC 命令后,才按照顺序依次执行队列中的所有操作(在 Redis 主线程中完成的,主线程会把事务中的操作都执行完,再处理别的客户端)。

因此,Redis 的事务的功能相比于 MySQL 来说,是弱化很多的。只能保证事务中的这几个操作是 “连续的”,不会被别的客户端 “加塞”,仅此而已。


为什么 Redis 不设计成和 MySQL 一样强大呢?

MySQL 的事务付出了很大的代价:

  • 在空间上,需要花费更多的空间来存储更多的数据。
  • 在时间上,也要有更大的执行开销。

正是因为 Redis 简单、高效的特点,才能够在分布式系统中弥补一些 MySQL 不擅长的场景。


什么时候需要使用到 Redis 事务呢?

如果我们需要把多个操作打包进行,使用事务是比较合适的。之前在多线程中是通过加锁的方式来避免 “插队” 的,而在 Redis 中直接使用事务即可。

在上面这个场景没有加锁也能解决问题。

Redis 命令里能够进行类似上图中的条件判断吗?

Redis 原生命令中确实没有这种条件判断,但是 Redis 支持 lua 脚本。通过 lua 脚本就可以实现上述的条件判定,并且也和事务一样是打包批量执行的。

lua 脚本的实现方式是 Redis 事务的进阶版本,此处对 lua 脚本不做过多的讨论。

注意:如果 Redis 是按照集群模式部署的话,是不支持事务的。 


二、事务操作

1、MULTI

开启一个事务,执行成功返回 OK。


2、EXEC

真正执行事务。

每次添加一个操作,都会提示 "QUEUED",说明命令已经进入客户端的事务队列中。此时如果另外开一个客户端,再尝试查询这几个 key 对应的数据,是没有结果的:

只有当真正执行 EXEC 的时候,客户端才会真正把上述操作发送给服务器,此时就可以获取到上述 key 的值了。

此时,另一个客户端再次查询结果也是如此。


3、DISCARD

放弃当前事务,此时直接清空事务队列,之前的操作都不会真正执行到。

当开启事务并给服务器发送若干个命令之后,服务器重启,那么此时这个事务怎么办呢?

此时的效果就等同于 discard。


4、WATCH

在执行事务的时候,如果某个事务中修改的值被别的客户端修改了,此时就容易出现数据不一致的问题。

客户端 1 先执行:

客户端 2 再执行:

客户端 1 最后执行:

此时 key 的值是多少呢?

从输入命令的时间看,是客户端 1 先执行的 set key 222,客户端 2 后执行的 set key 333。但是从实际的执行时间来看,是客户端 2 先执行的,客户端 1 后执行的。

由于客户端 1 得是 exec 执行了,才会真正执行 set key 222,所以这个操作实际上更晚执行,最终值就是 222.

这个时候其实就容易引起歧义。因此,即使不保证严格的隔离性,至少也要告诉用户,当前的操作可能存在风险。watch 命令就是用来解决上述这个问题的,watch 在该客户端上监控一组具体的 key,看看这个 key 在事务的 multi 和 exec 之间,set key 之后,是否在外部被其他客户端修改了。

  • 当开启事务的时候,如果对 watch 的 key 进行修改,就会记录当前 key 的 “版本号”(版本号可以理解成一个整数,每次修改都会使版本变大,服务器来维护每个 key 的版本号情况)
  • 在真正提交事务的时候,如果发现当前服务器上的 key 的版本号已经超过了事务开始时的版本号,就会让事务执行失败(事务中的所有操作都不执行)。

客户端 1 先执行:

watch 本质上是给 exec 加一个判定条件。

key 进行修改从服务器获取 key 的版本号是 0,记录 key 的版本号(还没真的修改,版本号不变)

这里只是入队列,但是不提交事务执行。

客户端 2 再执行:

修改成功,使服务器端的 key 的版本号 0 -> 1

客户端 1 最后执行:

exec 在执行上述事务中的命令时,此处就会做出判定。对比版本发现客户端的 key 的版本号是 0,服务器上的版本号是 1,版本不一致,说明有其他客户端在事务中间修改了 key,说明事务被取消了,于是真正执行 set key 222 的时候就没有真正执行。

客户端 2 执行:


(1)watch 的实现原理

watch 的实现类似于一个 “乐观锁”(不是指某个具体的锁,而指的是某一类锁的特性)。

  • 乐观锁(成本低):加锁之前就有一个心理预期,预期接下来锁冲突的概率比较低。
  • 悲观锁(成本高):加锁之前就有一个心理预期,预期接下来锁冲突(两个线程针对同一个锁加锁,一个能加锁成功,另一个就得阻塞等待)的概率比较高。

锁冲突概率高和冲突概率低,意味着接下来要做的工作是不一样的。

C++ Linux 中涉及到的锁 mutex / std::mutex 都是悲观锁,Java synchronized 则是可以在悲观和乐观之间自适应。


5、UNWATCH

取消对 key 的监控,相当于 WATCH 的逆操作。

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

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

相关文章

用 Python 编写的井字游戏

一.介绍 在本文中,我将向您展示如何使用 Python 创建一个非常简单的井字游戏。 井字游戏是一种非常简单的双人游戏。因此每次只能有两个玩家玩。该游戏也称为井字游戏或 Xs 和 Os 游戏。一个玩家玩 X,另一个玩家玩 O。在这个游戏中,我们有一…

树组件 el-tree 数据回显

树组件 el-tree 数据回显 树型结构的数据回显问题&#xff1a; 这里我只放了核心代码&#xff0c;主要是如何获取选中的树节点的id集合和如何根据树节点的id集合回显数据 大家根据需要自行更改&#xff01; <el-tree ref"authorityRef" node-key"id" …

SSH访问控制:精确管理你的服务器门户

“ 在数字世界中&#xff0c;服务器的安全性是任何网络管理员的首要任务。特别是对于远程登录协议如SSH&#xff0c;确保只有授权用户可以访问是至关重要的。 今天&#xff0c;记录两种有效的方法来控制用户对特定服务器的访问&#xff1a;通过sshd_config实现黑/白名单机制和利…

【Python】pandas:替换值、添加行/列,删除行/列,更改形状(含数据透视表)

pandas是Python的扩展库&#xff08;第三方库&#xff09;&#xff0c;为Python编程语言提供 高性能、易于使用的数据结构和数据分析工具。 pandas官方文档&#xff1a;User Guide — pandas 2.2.2 documentation (pydata.org) 帮助&#xff1a;可使用help(...)查看函数说明文…

前端面试宝典【HTML篇】【4】

欢迎来到《前端面试宝典》,这里是你通往互联网大厂的专属通道,专为渴望在前端领域大放异彩的你量身定制。通过本专栏的学习,无论是一线大厂还是初创企业的面试,都能自信满满地展现你的实力。 核心特色: 独家实战案例:每一期专栏都将深入剖析真实的前端面试案例,从基础知…

【区块链+绿色低碳】山东邹平:区块链生态环境监管平台 | FISCO BCOS应用案例

山东省滨州市生态环境局邹平分局通过实地考察和调研发现&#xff0c;执法大队在执法工作中存在各排污企业设备系统无 法互通、终端采集数据固证难且可信度低、环境执法电子证据采集规则与司法采信标准不统一等痛点。而区块链 的分布式记账、不易篡改性和智能合约自动执行机制&a…

【源码+文档+调试讲解】学生党务学习系统的设计与实现

摘 要 如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统大学生党务学习平台信息管理难度大&#xff0c;容错率低&…

前端技术回顾系列 14 | 总结 + Vue 3.x 必修课

欢迎关注公众号&#xff1a;CodeFit 创作不易&#xff0c;如果你觉得这篇文章对您有帮助&#xff0c;请不要忘了 点赞、分享 和 关注&#xff0c;为我的 持续创作 提供 动力&#xff01; 1. 回顾系列的初衷和目标 在六月初&#xff0c;我开始编写 「前端技术回顾系列 2024」&a…

C++基础知识:构造函数的分类和调用,有参构造和无参构造,有参构造和无参构造,三种调用方式:括号法,显示法,隐式转换法,以及相关代码演示和注意事项

1.构造函数的分类及调用: 2.两种分类方式: 按参数分为: 有参构造和无参构造 按类型分为:有参构造和无参构造 3.三种调用方式: 括号法 显示法 隐式转换法 2.调用方法代码演示 1.括号法代码演示&#xff1a; #include<iostream>using namespace std;//1.构造函数的分类和…

8、springboot3 vue3开发平台-后端-使用aop 添加系统访问日志

1. 添加依赖&#xff0c; 创建数据库 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><!-- IP地址解析 --><dependency><groupId>org.lionsou…

1000W长连接,如何建立和维护?千万用户IM 架构设计

1000W长连接&#xff0c;如何建立和维护&#xff1f;千万用户IM 架构设计 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如得物、阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的架构类/设计类…

【Vulnhub靶场AI-WEB-1.0打靶教程】

第一步&#xff1a;查看虚拟机的ip 第二步&#xff1a;扫描ip下开放的80端口 第三步&#xff1a;扫描查到的ip地址下的目录 第四步&#xff1a;访问查到的目录 访问robot.txt 第五步:访问robot.txt显示出的目录 第六步&#xff1a;打开kali终端&#xff0c;使用sqlmap功能 sq…

YOLO:训练自己的样本数据集进行目标检测

作者&#xff1a;CSDN _养乐多_ 本文将介绍如何使用python语言和 ultralytics 库训练自己的数据集&#xff0c;并进行 YOLO 目标检测模型训练和推理的代码。 文章目录 一、样本数据集准备1.1 标注工具1.2 数据集格式1.2.1 图片和标签数据集制作1.2.2 data.yaml制作 二、模型训…

canvas根据图片生成粒子动画

canvas根据图片生成粒子动画 效果展示&#xff1a; canvas根据图片生成粒子动画效果 注意&#xff1a; js和css的引入 id&#xff1a; cartoonDot-img对应的是被 拷贝的图像&#xff0c;后期要替换的 粒子图像就在这 min.js 地址 HTML代码块 <!DOCTYPE html> <h…

系统架构师考点--系统架构设计(中)

大家好。今天继续总结一下系统架构设计的一些考点。 一、软件架构复用 软件产品线是指一组软件密集型系统&#xff0c;它们共享一个公共的、可管理的特性集&#xff0c;满足某个特定市场或任务的具体需要&#xff0c;是以规定的方式用公共的核心资产集成开发出来的。即围绕核…

SpringBoot 日志:从基础到高级的全面指南

&#x1f4da; SpringBoot 日志&#xff1a;从基础到高级的全面指南 &#x1f50d; &#x1f4da; SpringBoot 日志&#xff1a;从基础到高级的全面指南 &#x1f50d;摘要引言正文内容一、日志概述 &#x1f4dc;二、日志使用 &#x1f4dd;2.1 打印日志 &#x1f4e3;2.2 日志…

IIS解析漏洞~ IIS7.漏洞分析

IIS解析漏洞 文件解析漏洞是由于中间件错误的将特殊格式的文件解析成可执行网页文件(脚本)&#xff0c;配合文件上传漏洞进行GetShell的漏洞&#xff01; 1.2&#xff1a;IIS7.X 在IIS7.0和IIS7.5版本下也存在解析漏洞&#xff0c;在默认Fast-CGI开启状况下&#xff0c;在一个文…

DM集群的高可用的配置方式(多语言)

一、介绍 强调以下&#xff1a;dm_svc.conf必须放置到应用服务器上才行&#xff0c;放到其他服务器上识别不到。 文章中有的框架可能没写到并不代表不支持&#xff0c;有没提到的可文章下方留言。 1.dm_svc.conf的作用&#xff1a; dm_svc.conf文件主要是为了当DM数据库集群…

PHP健身微信小程序系统源码

&#x1f3cb;️‍♀️健身新潮流&#xff01;解锁“健身微信小程序”的全方位塑形秘籍 &#x1f4f1;开篇&#xff1a;掌中健身房&#xff0c;随时随地动起来 你还在为找不到合适的健身场地或教练而烦恼吗&#xff1f;是时候告别这些束缚&#xff0c;拥抱“健身微信小程序”…

如何在数据埋点中发现和修复数据上报逻辑错误

如何发现和处理数据埋点中的逻辑错误 在大数据分析中,数据埋点是至关重要的一环。然而,当我们遇到数据上报逻辑错误时,该如何应对呢?本文将为你揭示解决这一棘手问题的有效方法。 目录 如何发现和处理数据埋点中的逻辑错误什么是数据上报逻辑错误?如何发现数据上报逻辑错误…