Redis:不只是缓存那么简单(十五)

专栏:Redis 修行录

个人主页:手握风云

目录

[一、Redis 事务](#一、Redis 事务)

[1.1. 基础概念](#1.1. 基础概念)

[1.2. 与 MySQL 事务核心区别](#1.2. 与 MySQL 事务核心区别)

[1.3. 底层原理](#1.3. 底层原理)

[1.4. 核心命令](#1.4. 核心命令)

[1. MULTI](#1. MULTI)

[2. EXEC](#2. EXEC)

[3. DISCARD](#3. DISCARD)

[4. WATCH](#4. WATCH)

[5. UNWATCH](#5. UNWATCH)


一、Redis 事务

1.1. 基础概念

Redis 事务与 MySQL 事务核心思路相似,都是把多条操作命令绑定为一组,实现批量统一执行。但 Redis 事务是弱化版事务,不完整满足数据库标准 ACID 四大特性,和 MySQL 事务存在巨大差异。

1.2. 与 MySQL 事务核心区别

  • 原子性(弱化)

MySQL 的原子性是指一组操作要么全部成功,一旦失败则全部回滚,恢复初始数据。Redis 的原子性仅保证命令连续批量执行不被插队,没有回滚能力:如果事务队列里某条命令语法报错,整个事务全部不执行;如果执行 EXEC 时某条命令运行报错,其余合法命令仍会正常执行,失败指令不会撤销,数据也不会恢复初始状态。

  • 一致性(不保证)

MySQL 的一致性保证事务执行前、执行后数据均合法有效,不会出现非法中间状态,依靠约束与回滚机制实现。Redis 无法保障一致性,它不存在数据约束,也没有回滚机制,事务执行过程中有可能产生非法数据状态。

  • 隔离性(完全不需要)

MySQL 存在多事务并发,设计多种隔离级别解决并发冲突。Redis 单线程串行处理所有客户端请求,同一时刻只会执行一组事务队列命令,事务内操作会一次性连续跑完,不会被其他客户端命令 "加塞",不存在事务并发场景,因此不需要隔离性、没有隔离级别。

  • 持久性(和事务无关)

MySQL 事务提交后数据永久落盘,具备持久性。Redis 数据默认存储在内存,持久化依靠 RDB/AOF 独立持久化方案控制,事务本身不具备持久化能力,两者互不绑定。

1.3. 底层原理

Redis 事务以服务器维护的专属事务队列作为核心载体。当通过 MULTI 命令开启事务后便进入入队阶段,客户端提交的所有操作命令不会立刻执行,而是仅存入事务队列,服务器返回 QUEUED 标识就代表命令入队成功。后续分为执行和放弃两种分支:发送 EXEC 命令时,服务器会一次性批量执行队列内全部缓存命令,事务正式生效;发送 DISCARD 命令时,则会直接清空事务队列,队列中所有命令全部作废,不会被执行。

1.4. 核心命令

1. MULTI

bash 复制代码
# 开启事务,初始化事务队列
MULTI

MULTI 是事务的开启命令,也是事务唯一的起始标识,执行后会返回 OK,完成事务队列初始化。执行该命令后客户端输入的所有读写指令不会立即执行,只会存入事务队列,返回 QUEUED 即代表命令成功入队;只有先执行 MULTI,客户端才能生成缓存命令的事务队列,一般用于批量数据操作前初始化事务环境。

2. EXEC

bash 复制代码
# 提交事务,批量执行队列内所有缓存命令
EXEC

EXEC 是事务提交命令,也是唯一能批量执行队列缓存指令的入口。它分两种执行逻辑,未搭配 WATCH 监控键时,会串行完整执行队列内全部命令,逐条返回每条指令的执行结果;若提前用 WATCH 监控了指定键,提交时会对比键的版本号,一旦服务器上键的版本号发生变更,EXEC 直接返回 nil,队列中所有操作全部不执行。执行 EXEC 阶段 Redis 单线程会优先处理当前事务,外部客户端请求需排队等待,适用于事务全部操作编写完成后统一提交生效。

3. DISCARD

bash 复制代码
# 放弃未提交事务,清空事务队列
DISCARD

DISCARD 是放弃未提交事务的命令,也是 Redis 在 EXEC 执行前撤销事务的唯一方式。执行后会直接清空事务队列里所有缓存指令,直接终止本次事务并返回 OK,不会对内存数据产生任何修改。由于 Redis 事务没有执行失败后的回滚机制,当编写事务中途决定放弃本次批量操作时,就可以使用 DISCARD 清空队列。

4. WATCH

bash 复制代码
# 乐观锁,监控一组指定 key,用于并发数据校验
WATCH key [key ...]

WATCH 属于乐观锁监控命令,必须在 MULTI 开启事务前执行,核心作用是监控一组指定键,完成并发数据校验。服务器会为每个键维护独立版本号,键每被修改一次版本号就自动自增;执行 WATCH 时会记录目标键当时的版本信息,后续调用 EXEC 提交事务时,会对比服务器当前键版本与事务记录版本,两者不一致就代表键被其他客户端篡改,整个事务直接失效,所有命令不执行,返回 nil。。该命令仅对当前客户端生效,不存在阻塞行为,多用于高并发场景,防止事务执行期间目标键被其他客户端修改造成数据不一致。

我们现在其中一个 Redis 客户端中执行事务 set k1 222,再在另一个 Redis 客户端中不加事务执行 set k1 333,再去执行 exec,就会发现最终值是"222"。

5. UNWATCH

bash 复制代码
# 取消当前客户端所有 WATCH 监控的 key
UNWATCH

UNWATCH 是取消键监控的命令,作为 WATCH 的逆向操作,手动执行后会清除当前客户端所有通过 WATCH 绑定的键版本监控记录,后续执行 EXEC 时不再做版本校验。

相关推荐
九皇叔叔3 小时前
【第二章】Redis基础入门:Redis是什么、为什么快以及核心特性详解
数据库·redis·缓存
云和恩墨3 小时前
删库不跑路,回滚极速触达——zData S“旁路日志”持续保护原理深剖
数据库
MetaLite4 小时前
SpringBoot接口分层规范-外网网关内部服务与参数边界
java·数据库·spring boot
Wang's Blog5 小时前
Java框架快速入门: Spring Security+OAuth2之元注解简化权限表达式
java·数据库·spring
蓝速科技7 小时前
医院导诊 AI 数字人一体机场景适配与落地指南丨蓝速科技
运维·数据库·人工智能·科技·自然语言处理·技术分享
QYR-分析7 小时前
重轨受电弓行业深度报告:市场格局、技术迭代与发展前景
大数据·数据库·人工智能
泡泡鱼(敲代码中)8 小时前
MySQL基础学习笔记:从数据模型到DDL全掌握
开发语言·数据库·笔记·学习·mysql
l1t9 小时前
DeepSeek总结的chdb-core v26.7.3发版说明
数据库·clickhouse·oracle
冰暮流星9 小时前
mysql之表子查询
数据库·mysql
Full Stack Developme10 小时前
CRM相关库表设计
数据库