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

初识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中的事务本身的内容也就不多,所以这里也算是简单的理解了一下就过了。


感谢阅读!

相关文章:

  • 项目组合管理PPM
  • 5.4.云原生与服务网格
  • uniapp返回上一页接口数据更新了,页面未更新
  • Lua 第9部分 闭包
  • 官方不存在tomcat10-maven-plugin插件
  • Linux内核源码结构
  • ApacheJmeter使用权威指南
  • Maven 工程中的pom.xml 文件(图文)
  • Python3(6) 运算符
  • 【解读】Chrome 浏览器实验性功能全景
  • Windows:注册表配置应用
  • STM32F103 “BluePill” 上的 DMA 原理与实践
  • Javase 基础入门 —— 03 面向对象编程
  • 欧拉环境(openEuler 22.03 LTS SP3)安装移动磐维数据库(PanWeiDB_V2.0-S2.0.2_B01)步骤
  • 【漫话机器学习系列】219.支持向量机分类器(Support Vector Classifier)
  • 【异常解决】Spring Boot 返回排序后的 Map 但前端接收顺序不对的解决方案
  • Django 实现电影推荐系统:从搭建到功能完善(附源码)
  • Django DRF实现用户数据权限控制
  • 什么是数据库的DDL和DML,有什么区别?
  • Ollama API 应用指南
  • 养胃不是顿顿喝粥,这份“胃的使用说明书”请收好
  • 宁德时代与广汽等五车企发布10款巧克力换电新车型:年内将完成30城1000站计划
  • 宁德时代校友红利!副董事长给母校复旦豪捐10亿,曾毓群给交大捐近14亿
  • 城事|喊侬白相,长兴太湖9号公路邀上海市民共赴诗意之旅
  • 网上销售假冒片仔癀和安宫牛黄丸,两人被判刑
  • 诸葛燕喃出任中央文化和旅游管理干部学院党委书记