当前位置: 首页 > backend >正文

初识Redis · 事务

目录

前言:

事务

涉及命令


前言:

前文我们花了大部分篇幅介绍了持久化,涉及到了RDB和AOF机制,涉及的文件有dump.rdb,appendonly.aof,涉及到的命令有save,bgsave,以及介绍了混合持久化的机制。并且理解了持久化主要是针对的Redis是一个内存级数据库的。

那么本文,我们就开始介绍一下Redis中的事务。


事务

提起事务,我们想必最开始想到的就是MySQL中的事务了,那么对于MySQL中的事务有四个特点,分别是:原子性,一致性,持久性,隔离性

而Redis相较于MySQL来说,它的事务就是MySQL一个min版本的,我们从四个特点分别展开。

原子性

在我们学习线程的时候,我们知道原子性的意思是要么0要么1,反正没有中间态。在我们学习MySQL的时候,我们知道原子性代表的是要么全部执行成功,要么全部不执行。所以MySQL中如果有事务失败了,那么就会进行回滚操作,把中间执行的的操作全部退了。

对于原子性来说,MySQL无异于是拉高了原子性的门槛,所以咱们说起原子性的时候,不是想起线程就是MySQL,对于Redis来说咱们有的时候实在是想不起来。

而对于Redis来说,它是否具备原子性呢?我们先来看看旧版本Redis的截图

旧版本的Redis是认为Redis具有原子性的,可是新版本的Redis的介绍确实这样的:

默默的把具备原子性的这句话删除了。

这就比较有意思的,其实最开始的原子操作的意思是要么全部执行,要么全部不执行,Redis是做到了这个最开始的意思的,而MySQL将门槛拉高到了全部执行成功,这就让Redis比较尴尬了。

于是后面,官方就把原子性这句话给删除了,要怪就只能怪MySQL了。

一致性

Redis是不具备一致性的,因为Redis不像MySQL具备回滚机制,它执行错了也就错了,就不管结果如何了,反正执行完毕就行,那么数据不一致的问题,自然是会有的。

持久性

Redis也是不具备持久性的,这因为它本身就是一个内存级的数据库,自然没有持久性,你要说之前的持久化操作和这里的持久性是不是一个东西,因为这里的持久性是事务中的,持久化机制可和事务没有任何关系了。

隔离性

Redis也是不具备隔离性的,因为Redis的是一个单线程模型,所有的操作都是串行执行的,也就不涉及隔离性了。

那么究竟什么是事务呢?

我们举个通俗的例子:

A和B去吃烤肉,A先到地方,先点好了单,B还没来,A给老板说先等会儿,一会儿再烤,过了一会儿B来了,A给老板说可以烤了。

在这个过程中,A等待B的时候尽管有客人来了,但是老板已经将烤A那桌的肉计划到任务列表了,所以即便有人在A之后来,也不会有插队的形式表现。

即Redis的事务是把任务打包之后,要求执行的时候再执行。

那么比如618的时候,针对一个上商品的库存,就容易引发线程安全的问题,此时就要涉及到加锁等问题,如果使用Redis的事务,就不用那么麻烦了。

开启事务之后,引入任务,执行操作,这个过程就能完美避免因为线程安全导致的问题,把事务push到队列里,使用命令exec的时候服务器才执行,也就不会存在对count同时--的情况了。

不过Redis的事务应用场景没有MySQl那么多,并且如果是集群模式的Redis就不支持事务了。


涉及命令

以上是理论支撑,我们也得使用使用对应的命令不是?

涉及到的命令有MULTI,EXEC,DISCARD,WATCH,UNWATCH

就这么多,MULTI是用来开启事务的,EXEC是用来执行事务的,DISCARD是用来丢弃事务的,WATCH是用来监视事务中的某个key的。

开启事务之后,我们输入set key1 111,此时我们另外启一个客户端,会发现查不了key1,此时我们再exec

exec代表执行事务,所以我们就能看到刚才入队列的事务成功被执行了,并且我们在另一个客户端也能查看到。

这也是一个非常形象的例子。

WATCH 是 Redis 提供的一种乐观锁机制,可以监视一个或多个 key,当你后续尝试执行事务(MULTI -> EXEC)时,如果 这些 key 在此期间被其他客户端修改过了,那么事务执行会失败(即 EXEC 返回 nil)。

我们可以实验一下:

 事务执行的时候,发现了key1被修改了,那么exec就拒绝执行了这次事务。

 注意到是拒绝执行这次事务,所以我们设置的key2也没有执行成功。

WATCH 的底层原理

Redis 在每个 key 的元信息中维护一个“修改计数”,相当于一个隐式的版本号。当你 WATCH key 时:

  1. Redis 把你 watch 的 key 加到客户端上下文中;

  2. 如果在你执行 EXEC 前,这些 key 被其他客户端修改(包括 SET/INCR/DEL 等),事务将失败;

  3. 相当于检测“版本冲突”。

这种方式实现了乐观锁,适合低并发或业务层对失败有兜底机制的场景。

小结

Redis 的事务机制相较于传统数据库而言比较“轻量”:

  • 不能回滚:中间命令失败不会影响其他命令;

  • 没有隔离级别:单线程保证串行,但无事务隔离;

  • 有乐观锁:WATCH 是一种简单但实用的乐观锁方案;

  • 不适合复杂业务:对高并发、高一致性要求场景,推荐 Lua 脚本 或 落地数据库事务控制。

在日常开发中,如果你只是想保证一串命令的串行性和基本的并发控制,Redis 的事务还是挺好用的。

因为Redis中的事务本身的内容也就不多,所以这里也算是简单的理解了一下就过了。


感谢阅读!

http://www.xdnf.cn/news/1362.html

相关文章:

  • HTTP:十一.HTTP认证概述
  • 12-DevOps-Gitlab托管Jenkinsfile
  • 使用 Conda 创建新环境
  • 关于Agent的简单构建和分享
  • 卷积神经网络(CNN)详细教程
  • LSTM-GAN生成数据技术
  • 计组1.2.3——计算机软件
  • 第十五届蓝桥杯 2024 C/C++组 合法密码
  • 《巧用DeepSeek快速搞定数据分析》书籍分享
  • 知识储备-DC综合相关
  • 大厂面试:MySQL篇
  • 深度剖析塔能科技精准节能方案:技术创新与实践价值
  • ShenNiusModularity项目源码学习(20:ShenNius.Admin.Mvc项目分析-5)
  • Git 远程操作全攻略:从基础到实战
  • jmeter中监控服务器ServerAgent
  • 华为开发岗暑期实习笔试(2025年4月16日)
  • 新品发布 | 6 秒全谱成像,VIX-N320 内置推扫式高光谱相机重磅发布
  • crictl 遇到报错 /run/containerd/containerd.sock: connect: permission denied
  • 设计模式--工厂模式详解
  • 【Docker】在Ubuntu平台上的安装部署
  • AIGC的爆发:哪些行业将被彻底颠覆?
  • Arduino示例代码讲解: Project 12 - Knock Lock 锁
  • # 06_Elastic Stack 从入门到实践(六)
  • 【MySQL】(7) 数据库设计
  • 【集合】底层原理实现及各集合之间的区别
  • 数据库操作
  • 遥感生物多样性产品
  • 【LLM】Ollama:容器化并加载本地 GGUF 模型
  • Agent系统工程实践:Langchain-Chatchat框架定制与优化
  • 计算机视觉算法实现——垃圾分类系统