Redis ①②-事务

在这里插入图片描述

Redis 事务

先来看看 MySQL 事务的四大特性:

  • 原子性:将事务里的多个操作打包成一个整体,要么全部成功,要么全部失败,失败后会进行回滚操作。
  • 一致性:确保事务执行前后,其数据的整体变化一致。
  • 隔离性:并发执行事务或其他操作时,对数据访问的隔离限制。
  • 持久性:事务完成后,对数据的修改持久化存储。

Redis 的事务与 MySQL 的事务相比,是稍逊一筹的。Redis 事务的特性可以说只有一个:“原子性”

且 Redis 是否是真正的原子性还持有争议。如果原子性按照 MySQL 事务的原子性定义,那么 Redis 事务其实是没有原子性的。

Redis 事务的原子性,就行将多个操作打包成一个整体,要么全部执行,要么全都不执行。这里的全部执行是不保证成功的

这和 MySQL 事务原子性是不同的,除了执行过程中出现错误的命令外,其他命令都能正常执行,并且,Redis 事务是不支持回滚(roll back)操作的。这与 MySQL 的略有不同。

旧版本 Redis 官网上对于事务的介绍中有这么一句话:

Either all of the commands or none are processed, so Redis transactions is also atomic. The EXEC command…

但现在 Redis 官网把这句话给删掉了,可见官方对于 Redis 事务的原子性也是比较虚的…

根据 MySQL 事务的四大特性,总结 Redis 事务的特性:

  • 弱化的原子性:Redis 没有回滚机制,只能做到这些操作批量执行,不能做到某条操作失败后就回到事务执行的初始状态。
  • 不保证一致性:Redis 没有回滚机制,也没有 “约束”。MySQL 的一致性体现的是运行事务前和运行后,结果都是合理有效的,不会出现中间非法状态。
  • 不需要隔离性:Redis 是单线程模型,并不存在并发执行事务的情况。
  • 不需要持久性:Redis 的数据主要还是保存在内存的,是否开启持久化和 redis-server 有关,不在 Redis 事务的考虑范围内。

Redis 事务的主要意义就是提供了一种将多个命令请求打包的功能。然后,再按顺序执行打包的所有命令,并且不会被中途打断。也就是当有其他客户端也执行命令时,不会出现 “插队” 的情况。

Redis 是如何实现事务的?在开启事务时,Redis 会为当前客户端额外创建一个队列。后续的命令操作都将进入这个队列,知道后续执行事务时,才将这些命令操作从队列中取出,执行。

在 Redis 主线程执行队列里的命令操作时,是不会处理其他客户端的命令请求的,知道队列的命令操作全部执行完毕。

MySQL 的事务确实非常强大,但是其在空间和时间上都花费了不小的资源和开销,是做出了一定的牺牲的。

而 Redis 主要的特点就是操作简单,速度快,性能高,常常作为 MySQL 服务器上游的缓存来使用。所以,其实并不需要像 MySQL 事务那样的强大。

Redis 事务实际开发中使用的非常少,功能比较鸡肋。往往用在那些会出现线程安全问题的地方,比如计数器等。且 Redis 是支持通过编写 Lua 脚本来执行一系列的操作,这也看出是一种事务

事务命令

使用 MULTI 开启事务,使用 EXEC 执行事务,使用 DISCARD 取消事务。

注意:开启事务后,将一些命令发送给服务器时,这些命令并不会立即执行,只有输入 EXEC 命令时,才会依此执行这些命令。

取消事务后,之前的发送给服务器的命令就都不会执行。

如果在开启事务时,且已经有几个命令发送给服务器了,此时服务器宕机了,那么就和 DISCARD 一样,取消了事务。

redis 127.0.0.1:6379> MULTI
OK
redis 127.0.0.1:6379(TX)> SET name redis
QUEUED
redis 127.0.0.1:6379(TX)> SET age 18
QUEUED
redis 127.0.0.1:6379(TX)> EXEC
1) OK
2) OK
redis 127.0.0.1:6379>

来看这么一个场景:

  • 客户端一:
redis 127.0.0.1:6379> SET k1 111 # 0️⃣
redis 127.0.0.1:6379> MULTI # 1️⃣
OK
redis 127.0.0.1:6379(TX)> SET k1 222  # 2️⃣
QUEUED
redis 127.0.0.1:6379(TX)> EXEC # 4️⃣
1) OK
redis 127.0.0.1:6379>
  • 客户端二:
redis 127.0.0.1:6379> SET k1 333 # 3️⃣

有上述两个客户端,按照后续的序号执行命令,也就是客户端一在开启事务后,发送服务器将 k1 设为 222 的命令,随即客户端二发送了 SET k1 333 命令并且执行了。最后客户端一执行了事务。

直接看的话,感觉最后 k1 的结果是 333。但结果却是 222。这是因为只有执行了 EXEC 命令,才会真正执行事务,之前的命令都只是进入了事务队列,还没有真正执行。所以,将 k1 设为 222 的命令是发生在客户端二执行之后的。

针对上述场景,会导致最后的结果产生歧义。我们可以在执行事务前通过 WATCH 监听 k1

WATCH 可以监听某个 key 是否在执行事务之间,与开启事务前的值有差异。如果监听到值有变化,则不执行修改该 key 的命令。

UNWATCH 可以取消对某个 key 的监听。

  • 客户端一:
redis 127.0.0.1:6379> WATCH k1 # 0️⃣
OK
redis 127.0.0.1:6379> SET k1 111 # 1️⃣
OK
redis 127.0.0.1:6379> MULTI # 2️⃣
OK
redis 127.0.0.1:6379(TX)> SET k1 222  # 3️⃣
QUEUED
redis 127.0.0.1:6379(TX)> EXEC # 5️⃣
(nil)
redis 127.0.0.1:6379>
  • 客户端二:
redis 127.0.0.1:6379> SET k1 333 # 4️⃣
OK
redis 127.0.0.1:6379>

通过上述操作,可以看到,客户端一执行 EXEC 了后,返回 (nil),说明该事务没有执行任何操作。最后 k1 的值也是 333。

这是因为其监听到了 k1 的值发生了变化,所以不执行修改 k1 的命令。

WATCH 的实现

WATCH 的实现是基于 "乐观锁"的,通过 CAS 原子操作判断 key 是否被修改。

在监听某个 key 时,会为该 key 生成一个 “版本号”,后续有其他客户端对该 key 进行修改时,会将该 key 的版本号增加。

在执行事务时,出现了对 key 进行修改的命令,会通过 CAS 操作判断其版本号与最初 WATCH 时的版本号是否一致。如果一致,则执行命令,否则,放弃执行该命令。

至于为什么要是有版本号而不是直接使用 key 的值判断,是为了避免 ABA 问题的出现。

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

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

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

相关文章

Leetcode+JAVA+回溯

39.组合总和 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。 candidates 中的 同一个 数字可以 无限制重复…

嘉讯科技:医院电子病历系统的关键性作用

电子病历系统在现代医疗领域发挥着至关重要的作用。 电子病历系统极大地提高了医疗效率。以往,医生需要翻阅大量的纸质病历,耗费时间和精力去查找关键信息。而电子病历系统通过数字化的存储和检索方式,使得医生能够在短时间内获取患者的完整病…

解决 Docker 里 DrissionPage 无法连接浏览器的问题,内含直接可用的Docker镜像(DrissionPage 浏览器链接失败 怎么办?)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 报错现象与诊断 📒📑 源码🐞 DrissionPage 报错内容🐞 手动启动 Chrome 测试📒 原因分析与解决方案 📒🔍 为什么会这样?🔧 解决办法🔧 推荐方案🎯 测试🐳 可直接使用的Docker镜像 🐳📦 镜像下载地址…

Mysql 数据库中设备实时状态表水平分表

一、 需求概述 在使用 Mysql 数据库存储设备上报日志时,存在一张设备实时状态表,随着时间推移,数据量变得十分庞大。为了更好地管理和查询数据,提高数据库性能,需要对该表进行水平分表操作。同时,存在分页…

nginx的下载与安装 mac

1. 下载 方法一:本地下载 链接:https://nginx.org/en/download.html(可直接搜官网) 下载到本地后,上传到linux的某个文件夹中 方法二:直接linux上下载(推荐) wget -c http://ngi…

在 Mac 上配置 Charles,抓取 iOS 手机端接口请求

工具官网:https://www.charlesproxy.com/ Charles 激活码 一、简介 Charles 是一款强大的网络抓包工具,支持 HTTP 和 HTTPS 协议,适用于调试手机 App、微信小程序、H5 页面等网络请求。 它能作为代理服务器,转发并记录本机及其他…

较大项目 git(gitee, github) 拉取失败解决方法

问题描述 近期遇到了一个拉取一个比较大项目失败的问题,229M这么大 每次都失败 我在自己的PC上,只有极好的环境才能拉取,笔记本办公热点怎么都不行 解决办法 后面通过https链接 首次会报错,因为我输入错了gitee的username&am…

爬虫中网络知识基础

HTTP(HyperText Transfer Protocol)和 HTTPS(HyperText Transfer Protocol Secure)是互联网上用于传输网页内容等数据的两种主要协议,以下是它们的定义和基本工作原理: HTTP 定义 :HTTP 是一种…

安全工具-二进制安全-testssl.sh

1 需求 --openssl <PATH> &#xff1a;use this openssl binary (default: look in $PATH, $RUN_DIR of testssl.sh) --quiet&#xff1a;dont output the banner. By doing this you acknowledge usage terms normally appearing in the banner --severity <severity…

WHAT - 组件库与 Storybook

文章目录 什么是 Storybook&#xff1f;使用场景举例快速上手教程&#xff08;React 为例&#xff09;1. 安装 Storybook2. 创建一个 Story&#xff08;组件故事&#xff09;3. 启动 Storybook 常用功能常见生态扩展示例&#xff1a;用 Args 和 Controls 动态控制 Props推荐资料…

魔音音乐 5.0.2 | 无损下载 同步网易云歌单UI美观

魔音音乐是一款功能丰富的音乐播放软件&#xff0c;提供高保真音质、智能推荐系统和用户友好界面。其丰富的音乐库几乎覆盖了所有类型的音乐&#xff0c;无论是流行歌曲还是小众音乐&#xff0c;都能在这里找到。这款应用非常适合音乐爱好者使用&#xff0c;它不仅让你享受高品…

云原生时代的中国答案:OLARDB、OceanBase与PostgreSQL的共生革命

以下是对阿里自研数据库的全景式技术调查,重点梳理其产品体系、与PostgreSQL的技术关联及发展历程: 一、阿里自研数据库全景图谱 ​​1. 核心自研产品​​ ​​数据库名称​​​​类型​​​​技术定位​​​​与PostgreSQL关系​​​​PolarDB​​云原生分布式数据库存储计…

HTTP 请求方法与状态码

前言&#xff1a;构建可靠前端应用的 HTTP 通信基础 在当今复杂的 Web 应用生态中&#xff0c;前端开发已远超简单的页面构建&#xff0c;转而成为与后端系统紧密交互的复杂体系。作为这一交互的核心机制&#xff0c;HTTP 协议承载着几乎所有的前后端数据交换&#xff0c;其设…

WIFI原因造成ESP8266不断重启的解决办法

一、报错 报错信息如下&#xff1a; 21:37:21.799 -> ets Jan 8 2013,rst cause:2, boot mode:(3,7) 21:37:21.799 -> 21:37:21.799 -> load 0x4010f000, len 3424, room 16 21:37:21.799 -> tail 0 21:37:21.799 -> chksum 0x2e 21:37:21.799 -> loa…

13.5-13.8. 计算机视觉【2】

文章目录 13.5. 多尺度目标检测13.5.1. 多尺度锚框13.5.2. 多尺度检测13.5.3. 小结 13.6. 目标检测数据集13.6.2. 读取数据集13.6.3. 演示 13.7. 单发多框检测&#xff08;SSD&#xff09;13.7.1. 模型13.7.1.1. 类别预测层13.7.1.2. 边界框预测层13.7.1.3. 连结多尺度的预测13…

RSS解析并转换为JSON的API集成指南

RSS解析并转换为JSON的API集成指南 引言 随着互联网的发展&#xff0c;信息的传播和共享变得越来越重要。RSS&#xff08;简易信息聚合&#xff09;作为一种广泛采用的格式&#xff0c;用于发布经常更新的内容&#xff0c;如博客文章、新闻头条或播客等。它允许用户订阅这些内…

java数据类型详解篇

1、8种基本数据类型 数据类型分类字节数内存位数是否最高位为符号位&#xff08;0正数1负数&#xff09;取值范围&#xff08;数值形式&#xff09;取值说明byte整数类型18是-128 ~ 127-2^7 ~ 2^7 - 1 &#xff08;幂形式&#xff09;short整数类型216是-32,768 ~ 32,767-2^15…

vue 浏览器样式警告:“unknown property name“

浏览器样式警告&#xff1a;"unknown property name"&#xff0c;但在部分电脑上的浏览器又是没有问题的。 这个问题因为没有安装sass或者less&#xff0c;却直接使用了他的语法&#xff0c;比如嵌套样式&#xff1a; body {/* 按钮 */.el-button {background: lin…

postgresql DDL脚本

在PostgreSQL中&#xff0c;数据定义语言&#xff08;DDL&#xff09;脚本用于定义、修改或删除数据库的结构。DDL 操作包括创建表、修改表结构、删除表等。以下是几种常见的DDL操作示例以及如何在脚本中实现它们。 1. 创建表 CREATE TABLE employees (employee_id SERIAL PR…

C#语言入门-task3 :C# 语言的面向对象技术

C# 面向对象编程技术概述 C# 是一种现代化的面向对象编程语言&#xff0c;提供了丰富的特性来支持面向对象的编程范式。以下是 C# 中面向对象编程的核心概念和技术&#xff1a; 核心概念 1. 类与对象 类是对象的蓝图&#xff0c;定义了对象的属性和行为。对象是类的实例。 …