Redis 7.x 系列【18】事务

有道无术,术尚可求,有术无道,止于术。

本系列Redis 版本 7.2.5

源码地址:https://gitee.com/pearl-organization/study-redis-demo

文章目录

    • 1. 概述
    • 2. 命令
      • 2.1 MULTI
      • 2.2 EXEC
      • 2.3 DISCARD
      • 2.4 WATCH
      • 2.5 UNWATCH
    • 3. 事务中的错误
    • 4. 和数据库事务的区别
      • 4.1 原子性
      • 4.2 隔离性
      • 4.3 持久性
      • 4.4 一致性
    • 5. 脚本和事务

1. 概述

官方文档

Redis 事务:允许在单个步骤中执行一组命令,其核心命令包括 MULTIEXECDISCARDWATCH

Redis 事务提供了两个重要的保证:

  • 所有事务中的命令都是串行化执行的,按顺序逐一执行。在事务执行过程中,不会在命令执行的中间阶段响应其他客户端的请求,这确保了命令作为单个隔离操作执行。
  • EXEC 命令触发事务中所有命令的执行:
    • 如果客户端在调用 EXEC 命令之前在事务上下文中失去了与服务器的连接,那么所有操作都不会执行。
    • 一旦调用 EXEC 命令,所有操作将被执行。
    • 在使用AOF时,确保使用单个系统调用将事务写入磁盘。如果Redis服务器崩溃或被系统管理员强制终止,可能会导致仅部分操作被记录。会在重新启动时检测到此条件,并报错退出。通过使用 redis-check-aof 工具,可以修复追加写入文件,删除部分事务,以便服务器能够重新启动。

自版本 2.2 起,Redis在上述两个保证之外提供了额外的保证,采用了乐观锁的方式,与检查和设置(CAS)操作非常类似。

注意Redis 不支持事务的回滚操作,因为支持回滚会对 Redis 的简单性和性能产生影响。

2. 命令

MULTIEXECDISCARDWATCHRedis 事务相关的命令。

2.1 MULTI

MULTI 命令用于开启一个事务,它总是返回 OK MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中, 当 EXEC命令被调用时, 所有队列中的命令才会被执行。

当客户端处于事务状态时, 所有传入的命令都会返回一个内容为 QUEUED 的状态回复, 这些被入队的命令将在 EXEC 命令被调用时执行。

示例:

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379(TX)> set k1 v1 
QUEUED
127.0.0.1:6379(TX)> set k2 v2
QUEUED

2.2 EXEC

EXEC 命令用于执行事务队列内的所有命令,返回值为事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值 nil

示例:

127.0.0.1:6379(TX)> exec 
1) OK
2) OK

2.3 DISCARD

DISCARD 命令用于取消事务,放弃执行事务队列内的所有命令,恢复连接为非事务模式。

示例:

127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set k2 v2
QUEUED
127.0.0.1:6379(TX)> discard 
OK

2.4 WATCH

WATCH 命令用于监视一个或多个 key ,当被 WATCHkey 被修改时,事务才会被执行。如果在事务执行期间这些键被其他客户端修改,那么该事务执行会被打断。

基本语法:

WATCH key [key ...]

示例,客户端监视 k1
在这里插入图片描述
打开另外一个客户端,对 k1 进行修改操作:
在这里插入图片描述
之前的客户端执行事务操作时,EXEC 返回 nil
在这里插入图片描述

注意事项:

  • Redis 6.0.9之前的版本中,过期的键不会导致事务中止。
  • WATCH 命令仅在事务中使用才有意义,因为它是为了配合事务而设计的乐观锁机制。
  • WATCH 可以被调用多次,从调用开始,直到EXEC调用结束。
  • 被监视的 key 在事务执行之前,会被Redis服务器记录下来,并在执行 EXEC 命令时检查这些键是否被修改。
  • 如果在 WATCHEXEC 之间发生了其他客户端的写操作,事务将会失败。此时,客户端可以根据返回值 nil 来判断事务执行是否成功。
  • 一旦执行 EXEC 或者关闭客户端连接,所有的 WATCH 都会被取消。
  • WATCH 命令在处理并发操作时非常有用,它可以帮助保证事务的原子性和一致性,是实现复杂事务逻辑的重要组成部分。

使用场景:

  • 实现乐观锁:WATCH 命令允许在事务执行前检查键是否被其他客户端修改,从而避免并发冲突,是实现乐观锁的重要手段之一。
  • 事务中的条件控制:当事务需要根据某些条件来执行或取消执行时,可以使用 WATCH 来检查条件是否满足。

2.5 UNWATCH

UNWATCH 命令用于取消 WATCH 命令对所有 key 的监视。如果执行过 EXECDISCARD,会自动取消监视,无需再执行 UNWATCH

示例:

localhost:0>UNWATCH
"OK"

3. 事务中的错误

Redis 事务中,可能会遇到两种类型的命令错误:

  • 在调用EXEC之前,某些命令可能会失败无法入队。例如,命令可能存在语法错误,或者可能出现关键条件,例如内存不足等。
  • 在调用EXEC之后,某些命令可能会失败。例如,可能对一个键执行了与其值类型不符的操作,例如对字符串值执行列表操作等。

Redis 2.6.5 开始,服务器会在累积命令期间检测到错误。如果发现错误,它将拒绝执行事务并在EXEC期间返回错误,丢弃该事务。而在EXEC之后发生的错误不会以特殊方式处理,即使事务中的某些命令失败,其他所有命令仍将被执行。

示例,在调用EXEC之前的命令存在语法错误时,不会被添加到队列:

localhost:0>MULTI
"OK"
localhost:0>INCR a b c
"ERR wrong number of arguments for 'incr' command"

示例,命令的语法都是正确的,在调用EXEC之后,由于 LPOP 操作的对象是一个字符串,所以这个命令执行失败,但是队列中的其他命令仍会被执行:

localhost:0>MULTI
"OK"
localhost:0>SET a abc
"QUEUED"
localhost:0>LPOP a
"QUEUED"
localhost:0>SET b efg
"QUEUED"
localhost:0>EXEC1)  "OK"2)  "WRONGTYPE Operation against a key holding the wrong kind of value"3)  "OK"

4. 和数据库事务的区别

关系型数据库事务:事务保证一系列操作要么全部成功,要么全部失败,如果某一步出现了异常,数据就会回滚,把之前的操作撤销。数据库事务需要满足四大特性(简称ACID),即原子性隔离性持久性一致性,才能保证数据正确性。

4.1 原子性

关系型数据库事务具有严格的原子性,要么所有操作都执行成功并永久保存(提交),要么所有操作都不执行(回滚)。

Redis 事务允许一组命令作为一个原子操作进行执行。但是,不是严格的原子性,如果在执行期间发生错误,部分命令可能已经执行,而另一部分可能未执行。

4.2 隔离性

关系型数据库事务通过锁和多版本并发控制(MVCC)等机制来实现不同事务之间的隔离性,例如读未提交、读已提交、可重复读和串行化等级别。

Redis事务提供了一定的隔离性,但没有像传统数据库那样严格的隔离级别。不同客户端的事务可能会相互干扰,需要通过WATCH命令显式地实现乐观锁机制。

4.3 持久性

关系型数据库事务中,事务提交后,数据会被持久化到磁盘,保证数据不会丢失。

Redis 通过持久化机制来实现持久性,但在事务提交时并没有严格保证数据已经永久保存。

4.4 一致性

关系型数据库事务中,发生错误时,数据库可以进行回滚操作,保证事务执行前后数据的一致性。

Redis事务中的某个命令执行失败,后续的命令仍然会继续执行,不会回滚已经执行的命令,无法保证一致性。

5. 脚本和事务

从定义上来说, Redis 中的脚本本身就是一种事务, 所以任何在事务里可以完成的事, 在脚本里面也能完成。 并且一般来说, 使用脚本要来得更简单,并且速度更快。

因为脚本功能是 Redis 2.6 才引入的, 而事务功能则更早之前就存在了, 所以 Redis 才会同时存在两种处理事务的方法。

不过官方并不打算在短时间内就移除事务功能, 因为事务提供了一种即使不使用脚本, 也可以避免竞争条件的方法, 而且事务本身的实现并不复杂。

不过在不远的将来, 可能所有用户都会只使用脚本来实现事务也说不定。 如果真的发生这种情况的话, 那么将废弃并最终移除事务功能。

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

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

相关文章

无法识别为 cmdlet、函数、脚本文件或可运行程序的名称

一、遇到问题 PS D:\software\nacos\nacos-server-2.3.1\bin> startup.cmd -m standalone startup.cmd : 无法将“startup.cmd”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径, 请确保路径正确,然后…

Ubuntu su命令输入密码后提示“su: 认证失败”

在Ubuntu系统中,使用su命令切换到root用户时提示“su: 认证失败”通常是因为root账户默认情况下是被锁定的,没有设置密码。以下是一些解决这个问题的方法: 使用sudo命令:Ubuntu推荐使用sudo命令代替直接使用root用户。sudo命令允许…

Aavegotchi的Gotchiverse新地图: 沉睡的野兽即将苏醒!

Gotchi 守护者们,准备好了,因为我们要大开杀戒了! 加入我们吧(后果自负!),我们将深入Gotchiverse,前往奥姆夫山--我们虚拟世界中所有 FOMO 的炽热源头。 请继续阅读,了解…

AI 绘画的常用技巧和操作方法

随着人工智能技术的飞速发展,AI 绘画已经成为设计和艺术领域的一股新兴力量。无论是设计师、艺术家,还是普通的科技爱好者,都能通过 AI 绘画工具创造出令人惊叹的作品。 AI 绘画的基本原理 AI 绘画的核心在于机器学习算法。通过训练大量的图像…

餐饮界的新传奇:沃可趣员工社区,让品牌关怀在指尖流淌

咖啡师与顾客发生肢体冲突、员工用咖啡粉泼顾客……某精品咖啡一天爆出两个大瓜! 很快有网友指出咖啡店员工长期遭受重压,与品牌之间存在根本矛盾。 同样做餐饮的老牌快餐,门店密度与之不相上下,却很少发生这样的暴雷。 不仅因…

算法力扣刷题 三十一【150. 逆波兰表达式求值】

前言 栈和队列篇。 记录 三十一【150. 逆波兰表达式求值】 一、题目阅读 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 、-、* 和 / 。 每个操作…

Django创建项目(1)

运行 注意 在本次创建Django项目时,出现了一点小问题,由于我之前pip换源过,换源用的是http,结果在创建时,pip只支持https,所以如果出现创建项目失败的问题,那么有可能是因为换源的问题&#xf…

(三十一)Flask之wtforms库【剖析源码下篇】

每篇前言: 🏆🏆作者介绍:【孤寒者】—CSDN全栈领域优质创作者、HDZ核心组成员、华为云享专家Python全栈领域博主、CSDN原力计划作者 🔥🔥本文已收录于Flask框架从入门到实战专栏:《Flask框架从入…

AlphaGo 背后的人工智能:机器学习和神经网络

文章目录 一、说明二、背景三、围棋游戏四、AlphaGo 算法五、神经网络六、AlphaGo 的未来七、人工智能的未来八、结论 一、说明 棋盘游戏围棋被视为人工智能最具挑战性的任务之一,因为它“复杂、基于模式且难以编程”。计算机程序 AlphaGo 战胜李世石成为人工智能和…

Redis 五大数据类型底层原理

0、前言 本文涉及的主题: redis 对象存储 底层数据结构:int、embstr、raw、ziplist、listpack、quicklist、skiplist、intset、hashtable redis 数据类型:string、list、set、zset、hash 1、对象存储、底层编码、数据类型 1.1 对象存储…

14-23 深度神经网络的主要架构(RNN/LSTM/CNN)

神经网络架构 神经网络的架构决定了这些网络如何运行,这是执行各种任务和扩展神经网络应用的关键因素,主要有两种方法:前馈神经网络和反馈神经网络。在本文中,在彻底分析每种方法之后,我们将对这两种架构进行深入比较…

规则·理解·成长:与自闭症儿童共绘记忆蓝图

在星贝育园,作为专注于自闭症儿童康复的专业教育者,我们常常遇到家长的疑惑:“为什么我的孩子总是记不清楚规则?”这个问题触及了自闭症谱系障碍(ASD)儿童在理解与遵守规则方面面临的独特挑战。下面&#x…

每日一题——Python实现PAT乙级1005 继续(3n+1)猜想(举一反三+思想解读+逐步优化)五千字好文

一个认为一切根源都是“自己不够强”的INTJ 个人主页:用哲学编程-CSDN博客专栏:每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 我的写法 代码逻辑概述 时间复杂度分析 空间复杂度分析 总结 我要更强 代码优化点…

【MySQL基础篇】函数及约束

1、函数 函数是指一段可以直接被另一段程序程序调用的程序或代码。 函数 - 字符串函数 MySQL中内置了很多字符串函数,常用的几个如下: 函数功能CONCAT(S1,S2,...,Sn)字符串拼接,将S1,S2,...,Sn拼接成一个字符串LOWER(str)将字符串str全部…

【热部署】✈️Springboot 项目的热部署实现方式

目录 🍸前言 🍻一、热部署和手动重启 🍺二、热部署的实现 2.1 手动启动热部署 2.2 自动检测热部署 2.3 关闭热部署 💞️三、章末 🍸前言 小伙伴们大家好,书接上文,通过Springboot 中的 actu…

提升TK直播体验:使用美国直播网络的六大优势

国内有许多公司想在TikTok上进行美国直播,但由于TikTok的政策限制,在国内直接访问存在困难。然而,通过使用Ogcloud的美国直播网络,这一问题得以解决。那么,TikTok海外直播使用美国直播网络具体有哪些优势呢&#xff1f…

【懒删除堆 优先队列】1172. 餐盘栈

本文涉及知识点 懒删除堆 优先队列 LeetCode1172. 餐盘栈 我们把无限数量 ∞ 的栈排成一行,按从左到右的次序从 0 开始编号。每个栈的的最大容量 capacity 都相同。 实现一个叫「餐盘」的类 DinnerPlates: DinnerPlates(int capacity) - 给出栈的最大…

stm32中IIC通讯协议

参考资料:大部分均引用b站江协科技课程、GPT及网络资料 什么是IIC(i2C)通讯协议? 关键字:SCL、SDA、半双工、同步、串行。 IIC(Inter-Integrated Circuit),也称为I2C(In…

不同的llm推理框架

vLLM适用于大批量Prompt输入,并对推理速度要求比较高的场景。 实际应用场景中,TensorRT-LLM通常与Triton Inference Server结合起来使用,NVIDIA官方能够提供更适合NVIDIA GPU运行的高效Kernel。 LightLLM比较轻量、易于扩展、易于上手&…

Linux—KVM虚拟化中使用基本命令管理虚拟机(纯实例)

🏡作者主页:点击! 👨‍💻Linux高级管理专栏:点击! ⏰️创作时间:2024年7月2日11点11分 🀄️文章质量:94分 文章目录 前言 1.查看命令帮助 2.查看KVM 的…