系列导读:本篇将深入讲解 Redis 事务机制,包括事务命令、WATCH 监控、Lua 脚本等核心内容。
文章目录
-
- 一、事务基础
-
- [1.1 事务特性](#1.1 事务特性)
- [1.2 事务执行流程](#1.2 事务执行流程)
- 二、事务命令详解
-
- [2.1 基本事务](#2.1 基本事务)
- [2.2 取消事务](#2.2 取消事务)
- [2.3 事务错误处理](#2.3 事务错误处理)
- [三、WATCH 监控](#三、WATCH 监控)
-
- [3.1 乐观锁机制](#3.1 乐观锁机制)
- [3.2 取消监控](#3.2 取消监控)
- [3.3 实战示例:转账](#3.3 实战示例:转账)
- [四、Lua 脚本](#四、Lua 脚本)
-
- [4.1 EVAL 命令](#4.1 EVAL 命令)
- [4.2 分布式锁示例](#4.2 分布式锁示例)
- [4.3 脚本缓存](#4.3 脚本缓存)
- 总结
一、事务基础
1.1 事务特性
┌─────────────────────────────────────────────────────────────┐
│ Redis 事务特性 │
├─────────────────────────────────────────────────────────────┤
│ ✅ 批量操作:多个命令打包执行 │
│ ✅ 顺序执行:按入队顺序执行 │
│ ✅ 隔离性:事务执行期间不被其他命令打断 │
│ ⚠️ 非原子性:某命令失败不影响其他命令 │
└─────────────────────────────────────────────────────────────┘
1.2 事务执行流程
MULTI → 命令入队 → EXEC → 执行所有命令
│ │
└── DISCARD 取消 ───┘
二、事务命令详解
2.1 基本事务
bash
# 开始事务
MULTI
# 命令入队
SET key1 "value1"
SET key2 "value2"
INCR counter
# 执行事务
EXEC
# 返回每个命令的结果
# 1) OK
# 2) OK
# 3) (integer) 1
2.2 取消事务
bash
MULTI
SET key1 "value1"
SET key2 "value2"
# 取消事务
DISCARD
2.3 事务错误处理
bash
# 语法错误:整个事务不执行
MULTI
SET key1 "value1"
INCR key1 key2 # 语法错误
EXEC
# 返回错误,所有命令都不执行
# 运行时错误:其他命令继续执行
MULTI
SET key1 "value1"
INCR key1 # key1不是数字,运行时错误
SET key2 "value2"
EXEC
# 1) OK
# 2) (error) ERR value is not an integer
# 3) OK
三、WATCH 监控
3.1 乐观锁机制
bash
# 监控键
WATCH balance
# 检查余额
GET balance # 假设返回 100
# 开始事务
MULTI
DECRBY balance 50
EXEC
# 如果balance被其他客户端修改,EXEC返回nil
3.2 取消监控
bash
# 取消所有监控
UNWATCH
3.3 实战示例:转账
bash
# 转账事务
WATCH from_account to_account
GET from_account
GET to_account
MULTI
DECRBY from_account 100
INCRBY to_account 100
EXEC
四、Lua 脚本
4.1 EVAL 命令
bash
# 执行Lua脚本
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
# KEYS数组:KEYS[1], KEYS[2]...
# ARGV数组:ARGV[1], ARGV[2]...
4.2 分布式锁示例
bash
# 加锁脚本
EVAL "
if redis.call('SETNX', KEYS[1], ARGV[1]) == 1 then
redis.call('EXPIRE', KEYS[1], ARGV[2])
return 1
else
return 0
end
" 1 lock:resource uuid 30
# 解锁脚本
EVAL "
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
else
return 0
end
" 1 lock:resource uuid
4.3 脚本缓存
bash
# 加载脚本
SCRIPT LOAD "return redis.call('GET', KEYS[1])"
# 返回SHA1: "abc123..."
# 执行缓存的脚本
EVALSHA abc123... 1 mykey
# 检查脚本是否存在
SCRIPT EXISTS abc123...
# 清除所有脚本
SCRIPT FLUSH
总结
本文我们学习了:
✅ 事务基础 :MULTI/EXEC/DISCARD
✅ WATCH 监控 :乐观锁机制
✅ Lua 脚本 :EVAL/EVALSHA
✅ 分布式锁:原子操作实现
下篇预告 :Redis 从入门到精通(十):管道技术
作者 :刘~浪地球
系列 :Redis 从入门到精通(九)
更新时间:2026-04-06