💡 一句话真相 :Redis事务就像"点套餐"🍱------把多个命令打包下单(
MULTI
),后厨(Redis)一次性烹饪(EXEC
),但某个菜缺货(失败)不会退单!
🔧 一、为什么需要事务?转账案例的痛点
场景:A向B转账100元
客户端 Redis GET A_balance → 500 GET B_balance → 300 SET A_balance 400 SET B_balance 400 客户端 Redis
风险 :若第二步后Redis宕机 → A扣款成功,B未到账!
🛠️ 二、Redis事务实现:三阶段流程
1. 开启事务(点餐下单)
bash
MULTI # 开启事务 → 返回OK
效果:后续命令进入队列,不立即执行
2. 命令入队(选菜品)
bash
DECRBY A_balance 100 # A账户减100 → 进入队列
INCRBY B_balance 100 # B账户加100 → 进入队列
特性:
- 语法错误(如
INCRBY B 100
)直接拒绝入队 - 运行时错误(如对字符串
DECRBY
)不检查
3. 执行事务(后厨烹饪)
bash
EXEC # 执行队列中所有命令
输出示例:
1) (integer) 400 # DECRBY结果
2) (integer) 400 # INCRBY结果
🚨 三、原子性≠回滚:核心差异图解
事务开始 命令1成功 命令2失败 命令3执行 事务提交
与传统数据库对比:
特性 | Redis事务 | MySQL事务 |
---|---|---|
原子性 | 命令全部执行 | 全部成功或全部回滚 |
隔离性 | 单线程天然隔离 | 需设置隔离级别 |
错误处理 | 继续执行后续命令 | 自动回滚 |
回滚支持 | ❌ 无 | ✅ 有 |
💥 关键结论 :Redis事务是 "部分原子性" ------ 保证命令打包执行,但不支持回滚!
🔒 四、乐观锁:Watch命令解决并发冲突
1. 秒杀库存超卖问题
客户端1 Redis 客户端2 GET stock → 10 GET stock → 10 DECR stock DECR stock 客户端1 Redis 客户端2
2. Watch实现乐观锁
bash
WATCH stock # 监控库存键
MULTI
DECR stock
EXEC # 若stock被其他客户端修改,EXEC返回(nil)
执行效果 :
3. 重试机制(代码示例)
python
import redis
r = redis.Redis()
def decr_stock():
while True:
try:
r.watch('stock')
stock = int(r.get('stock'))
if stock > 0:
pipe = r.pipeline()
pipe.multi()
pipe.decr('stock')
if pipe.execute(): # 执行成功返回非None
break
else:
print("库存不足")
break
except Exception:
continue # 冲突则重试
⚠️ 五、事务四大坑点与解决方案
坑点 | 现象 | 解决方案 |
---|---|---|
命令错误不回滚 | SET失败后DECR仍执行 | 开发阶段用redis-cli --pipe 检测语法 |
运行时错误继续执行 | 对字符串INCR → 继续执行事务 | 保证数据类型正确性 |
WATCH失效重试风暴 | 高并发时无限重试 | 设置最大重试次数/退避策略 |
事务内执行慢命令 | 阻塞其他客户端 | 避免KEYS 、大数据操作 |
💎 六、事务 vs Lua脚本:终极选择
特性 | 事务 | Lua脚本 |
---|---|---|
原子性 | 命令级 | 脚本级(真正原子) |
复杂度 | 简单 | 需学习Lua语法 |
性能 | 较高 | 超高(减少网络往返) |
错误处理 | 弱 | 强(可抛异常) |
Lua脚本示例:
lua
local stock = redis.call('GET', KEYS[1])
if tonumber(stock) > 0 then
redis.call('DECR', KEYS[1])
return 1 -- 成功
else
return 0 -- 失败
end
执行命令:
bash
EVAL "脚本内容" 1 stock
🔧 七、最佳实践:3类场景选型

- 简单命令组 → 事务(如:
MULTI
+SET A 1
+SET B 2
+EXEC
) - 原子计数器 → Lua脚本(如:库存扣减)
- 读后写冲突 →
WATCH
+ 事务(如:余额转账)
💡 八、总结:Redis事务三原则
- 非回滚设计:执行即提交,失败命令需业务补偿
- 隔离性保障:单线程执行天然隔离
- 乐观锁搭档 :
WATCH
解决并发冲突
🔥 黄金口诀:
- 简单打包用
MULTI
- 并发控制靠
WATCH
- 真原子操作选
Lua

#Redis事务 #高并发 #分布式系统
👉 关注我,下期揭秘《Redis+Lua实现分布式锁》!