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 时不再做版本校验。

相关推荐
weixin_307779132 小时前
Linux下Docker Compose里运行PostgreSQL数据库故障诊断Shell脚本
linux·运维·数据库·docker·postgresql
名字还没想好☜2 小时前
用 Redis + Redisson 实现分布式锁:从踩坑到生产可用
java·redis·分布式·junit·分布式锁·redisson
醉城夜风~2 小时前
MySQL 常用内置函数全解:字符串、数值、日期、流程控制实战教程
数据库·mysql
谙忆2 小时前
图片CDN与边缘优化实战:缓存策略、图片处理型CDN与动态裁剪
java·spring·缓存
程序猿秃头之路2 小时前
DDD 系列:实体和值对象详解
数据库·oracle·ddd·领域驱动设计
qiu_lovejun9982 小时前
linux安装docker和redis和rabbitmq和nginx和rocketmq和kafka
linux·redis·docker·kafka·rabbitmq·rocketmq
Database_Cool_3 小时前
阿里云 RDS MySQL vs 腾讯云 CDB 国内云关系型数据库深度对比
数据库·mysql·阿里云
xiaohaiAIgeo3 小时前
【2026年】基于三维建模的实验室智慧管理平台:暖通能源照明的数字孪生方案
大数据·数据库·人工智能·科普知识
深盾科技_Virbox3 小时前
软件授权工具静默安装实践
java·运维·数据库·安全·软件需求