Redis 事务
Redis 事务
核心事务指令
| 指令格式 | 功能说明 |
|---|---|
multi |
开启事务,后续指令将进入队列等待执行 |
watch key [key...] |
监听指定键,若这些键在事务执行前被其他操作修改,事务将触发回滚 |
unwatch key [key...] |
取消对之前监听键的监控 |
exec |
提交事务,执行队列中所有指令 |
discard |
回滚事务,放弃执行队列中所有指令 |
Redis 事务执行流程
Redis 流程清晰且易于操作:
- 开启事务:通过
multi指令启动事务,此时客户端进入事务上下文。 - 命令入队:后续输入的所有 Redis 指令不会立即执行,而是被依次加入事务队列,返回
QUEUED表示入队成功。 - 执行事务:通过
exec指令提交事务,Redis 会按队列顺序序列化执行所有指令;若需放弃执行,可通过discard指令回滚事务。
Redis 事务核心特点
- 隔离性:事务中的所有命令会被 Redis 序列化处理,按顺序执行,执行过程中不会被其他客户端的指令打断,保证操作的连续性。
- 原子性补充说明:Redis 事务的原子性与关系型数据库(如 MySQL)不同:
- 若事务队列中指令本身语法正确(入队时返回
QUEUED),即使部分指令执行失败(语法错误的指令回回滚),其他指令仍会继续执行,不会整体回滚; - 若需严格保证事务原子性(要么全部成功,要么全部失败),可结合 Lua 脚本实现。
- 若事务队列中指令本身语法正确(入队时返回
事务操作示例演示
示例 1:正常执行事务(部分指令执行失败不回滚)
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set com:username:10 peppa
QUEUED
127.0.0.1:6379(TX)> set com:age:10 5
QUEUED
127.0.0.1:6379(TX)> incr com:age:10
QUEUED
127.0.0.1:6379(TX)> incr com:username:10 # 字符串类型无法自增,执行会失败
QUEUED
127.0.0.1:6379(TX)> get com:age:10
QUEUED
127.0.0.1:6379(TX)> exec
1) OK # 第一个 set 指令执行成功
2) OK # 第二个 set 指令执行成功
3) (integer) 6 # incr 指令执行成功,age 从 5 变为 6
4) (error) ERR value is not an integer or out of range # incr 字符串失败
5) "6" # get 指令执行成功,获取到 age 最新值
127.0.0.1:6379>
说明:即使第 4 条 incr 指令执行失败,其他指令仍正常执行,体现了 Redis 事务部分失败不回滚的特性。

示例 2:监听键被修改,事务回滚
操作步骤:
- 客户端 1 监听键
cuit:hippo:username:10并开启事务:
127.0.0.1:6379> watch cuit:hippo:username:10
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set cuit:hippo:username:20 emiy
QUEUED
127.0.0.1:6379(TX)> set cuit:hippo:age:20 5
QUEUED
- 客户端 2 修改被监听的键
cuit:hippo:username:10:
127.0.0.1:6379> set cuit:hippo:username:10 mike
OK
- 客户端 1 提交事务,因监听键被修改,事务回滚:
127.0.0.1:6379(TX)> exec
(nil) # 返回 nil 表示事务回滚,队列中指令未执行
127.0.0.1:6379>
示例 3:指令语法错误,事务直接丢弃
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> set key # set 指令缺少参数,语法错误
(error) ERR wrong number of arguments for 'set' command
127.0.0.1:6379(TX)> exec
(error) EXECABORT Transaction discarded because of previous errors. # 事务因语法错误被丢弃
127.0.0.1:6379>

说明:若事务队列中存在语法错误的指令(入队时直接返回错误),提交事务时 Redis 会直接丢弃整个事务,不会执行任何指令。

浙公网安备 33010602011771号