
开篇介绍hello 大家本篇博客我们来学习Redis的事务那么我们之前MySQL就已经学习过了事务也就是MVCC和ACID那么我们本篇博客就来看看Redis的事务又是如何的呢第一节 Redis 事务是什么一、先搞懂什么叫「事务」不管是 Redis、MySQL、Oracle、SQL Server只要在计算机、数据库、缓存领域提到事务这两个字本质上都是一个完全统一、完全通用、完全不变的意思把好几个独立的、连续的、有逻辑关联的操作打包绑定成「一整组不可拆分、不可打断、不可捣乱的动作集合」这一组动作要么从头到尾一起全部做完要么就从一开始一个都别做、一个都不执行绝对不能出现「做了一半、剩下一半没做、中间被别人插一脚、一半成功一半失败」的混乱、错误、非法情况保证数据的安全、逻辑的正确、业务的稳定。举一个生事务例子你去商场的自动取款机ATM取钱完成一次取钱操作一共要做 3 件必须绑定在一起的核心事情验证你的银行卡密码系统确认是本人操作防止盗刷从你的银行卡账户里扣掉你要取的对应金额账户金额减少从取款机的出钞口吐出你要取的钞票拿到现金这 3 件事就是一个标准的、完美的、符合事务定义的真实事务如果密码输错 → 3 件事全部取消不扣钱、不吐钱回到初始状态如果扣钱成功、但取款机突然坏了吐不出钞票 → 银行系统必须自动把扣掉的钱退回到你的银行卡里这就是事务的回滚绝对不能出现「扣了你的钱却没吐钞票」「吐了钞票却没扣钱」这种半拉子、错误、不合理的情况。这就是事务存在的唯一意义保证一组有逻辑关联的操作的完整性、安全性、正确性不出任何乱子、不产生任何错误数据、不引发任何业务故障。二、Redis 事务 和 你熟悉的 MySQL 事务 —— 天差地别你如果学过关系型数据库 MySQL一定背过滚瓜烂熟的事务四大核心特性 ACID原子性Atomicity、一致性Consistency、隔离性Isolation、持久性Durability。但是Redis 事务根本不是完整意义上的标准事务它是「阉割版、弱化版、简易版、基础版」的事务Redis 只保留了事务「最基础、最底层、最简单的一点点功能」剩下 MySQL 拥有的所有强大、安全、严谨的事务特性Redis 全都没有一个都没有1. 原子性最关键区别直接决定了 Redis 事务的底线和上限MySQL 事务的原子性标准、完美、严谨要么全部成功要么全部失败失败自动回滚到事务开始前的初始状态就像 ATM 取钱扣钱失败 → 钱自动退回银行卡绝对不会出现「钱扣了、东西没拿到」「操作一半失败、数据错乱」的情况。Redis 事务的原子性弱化、残缺、无回滚没有回滚没有回滚没有回滚重要的事情说一百遍Redis 只能保证这一组命令按顺序、连续执行不被别人的命令插队、打断。如果中间有一条命令执行失败了前面已经执行成功的命令不会撤销、不会恢复、不会变回原来的样子、不会回滚错了就是错了烂摊子必须你自己手动收拾Redis 完全不管、完全不处理、完全不负责2. 一致性数据合不合法、规不规范、合不合理的问题MySQL 一致性严格、约束、合规事务执行完成后数据一定是合法的、符合规则的、合理的。比如银行卡余额不能是负数、学生成绩不能是负数、商品库存不能是负数MySQL 会通过约束、触发器、事务规则严格限制绝对不会出现非法数据。Redis 一致性无约束、无规则、无限制没有任何约束没有任何一致性保证完全自由完全不管你把用户余额改成 -10000、-100000、-1000000把商品库存改成 -999Redis 完全不管它只管执行你发的命令不管数据合不合法、合不合理、符不符合业务规则。3. 隔离性多个人同时操作数据会不会打架、会不会冲突、会不会错乱MySQL 隔离性复杂、严谨、多层级有 4 个标准隔离级别读未提交、读已提交、可重复读、串行化专门解决「多个人、多个事务同时改同一个数据」的并发冲突问题防止脏读、不可重复读、幻读、数据错乱。Redis 隔离性不需要、不存在、无级别根本不需要隔离性完全不存在隔离级别因为 Redis 是单线程工作模式同一时间Redis 只能执行一个命令或者一组事务不可能有「两个事务同时跑」「两个命令同时执行」的情况所以天然不会打架、不会冲突、不会错乱不需要任何隔离级别。4. 持久性数据会不会永久保存、断电会不会丢MySQL 持久性永久、落盘、安全事务一提交数据立刻写到物理硬盘里永久保存就算服务器关机、断电、重启、崩溃数据也不会丢、不会消失。Redis 持久性无关、分离、独立事务和持久化完全没关系一毛钱关系都没有Redis 数据默认存在内存里断电就丢、重启就没。是否把数据存到硬盘是 Redis 持久化机制AOF 追加文件、RDB 快照的功能和事务本身完全独立、完全分离事务只管「修改内存数据」不管「数据是否存硬盘」。三、Redis 事务的真正底层本质Redis 事务就是一个「专属的命令暂存队列」你对 Redis 输入MULTI→ 相当于跟快递站工作人员说「我接下来要寄好几个包裹先帮我暂存在我专属的仓库里别先派送别先发货」你发set、incr、del、hset等数据操作命令 → 相当于把包裹一个个放进快递站你的专属仓库Redis 会回复QUEUED意思是「包裹已入队暂存成功等待统一派送」你对 Redis 输入EXEC→ 相当于跟快递员说「现在把我仓库里所有包裹一次性、按顺序、全部派送出去一个都别落下」你对 Redis 输入DISCARD→ 相当于跟快递员说「这些包裹我不寄了全部扔掉、全部清空一个都别派送一个都别执行」Redis 事务在整个 Redis 体系里唯一能保证的事情只有这一件、就这一件、仅此一件事务里的所有命令会按你入队的顺序、连续、一次性、不间断执行中间绝对不会被其他客户端的命令插队、打断、插入、捣乱仅此而已仅此而已仅此而已没有其他任何保证没有其他任何特性没有其他任何功能第二节 Redis 事务 5 大核心命令Redis 事务一共就 5 个核心命令MULTI、EXEC、DISCARD、WATCH、UNWATCH一、MULTI开启事务标记接下来的命令全部暂存入队不立即执行1. 命令作用告诉 Redis 服务器从现在开始我发的所有数据修改、数据操作命令先不要执行、先不要生效、先不要改数据全部放进我这个客户端专属的事务队列里暂存起来等我后续发命令再统一处理2. 执行流程客户端在 Redis 命令行输入MULTI命令发送给 Redis 服务器服务器接收到命令后给当前客户端打上「事务模式开启」的专属标记服务器给当前客户端创建一个空的、专属的、独立的事务队列每个客户端的队列都是独立的互不干扰、互不影响服务器处理完成返回OK给客户端表示事务开启成功后续命令全部入队暂存。3. 完整实例127.0.0.1:6379 MULTI OK第一行你向 Redis 服务器发送「开启事务」的命令告诉 Redis 要开始打包命令了第二行Redis 服务器回复OK代表事务模式已成功开启后续所有数据操作命令全部进入事务队列暂存不执行、不生效。4. 关键注意点一个客户端同一时间只能开启一个事务绝对不能嵌套 MULTI比如在事务里再输 MULTI会直接报错开启事务后只有数据操作命令set、incr、del、hset、lpush 等会入队info、config、client等系统命令会直接执行不进入事务队列不同客户端的事务完全独立客户端 A 开事务不影响客户端 B 的正常命令执行互不干扰。5. 错误示范嵌套 MULTI直接报错127.0.0.1:6379 MULTI OK 127.0.0.1:6379 MULTI (error) ERR MULTI calls can not be nested报错原因Redis 事务不支持嵌套一个客户端只能开一个事务。二、EXEC执行事务一次性跑完队列里所有命令按顺序生效1. 命令作用告诉 Redis 服务器别暂存了别等了现在立刻、马上、按照我入队的顺序执行我刚才放进事务队列的所有命令全部生效全部执行2. 执行流客户端在 Redis 命令行输入EXEC命令发送给 Redis 服务器服务器接收到命令后从头到尾、按顺序遍历当前客户端的事务队列一条一条执行队列里的命令服务器把每条命令的执行结果按入队顺序打包成一个结果列表返回给客户端所有命令执行完成后服务器自动清空事务队列关闭事务模式后续客户端发送的命令恢复正常模式立即执行不再进入事务队列暂存。3. 完整实例# 第一步开启事务进入命令入队暂存模式 127.0.0.1:6379 MULTI OK # 第二步发送第一条string类型命令存入事务队列 127.0.0.1:6379 set k1 1 QUEUED # 第三步发送第二条string类型命令存入事务队列 127.0.0.1:6379 set k2 2 QUEUED # 第四步发送第三条string类型命令存入事务队列 127.0.0.1:6379 set k3 3 QUEUED # 第五步发送自增命令给k1加1存入事务队列 127.0.0.1:6379 incr k1 QUEUED # 第六步执行事务一次性运行所有队列命令 127.0.0.1:6379 EXEC 1) OK 2) OK 3) OK 4) (integer) 24. 返回结果详细解释1) OK第一条命令set k1 1执行成功k1 的值设为 12) OK第二条命令set k2 2执行成功k2 的值设为 23) OK第三条命令set k3 3执行成功k3 的值设为 34) (integer) 2第四条命令incr k1执行成功k1 从 1 自增为 2。5. 结果验证# 查看 k1 的值是事务里自增后的 2 127.0.0.1:6379 get k1 2 # 查看 k2 的值是事务里设置的 2 127.0.0.1:6379 get k2 2 # 查看 k3 的值是事务里设置的 3 127.0.0.1:6379 get k3 3所有命令全部按顺序生效没有被打断没有被插队没有出现任何错乱。6. 多数据类型事务实例hash、list、set扩充内容# 开启事务 127.0.0.1:6379 MULTI OK # hash类型操作 127.0.0.1:6379 hset user:1 name zhangsan age 20 QUEUED # list类型操作 127.0.0.1:6379 lpush list1 a b c QUEUED # set类型操作 127.0.0.1:6379 sadd set1 1 2 3 QUEUED # 执行事务 127.0.0.1:6379 EXEC 1) (integer) 2 2) (integer) 3 3) (integer) 3 # 验证结果 127.0.0.1:6379 hgetall user:1 1) name 2) zhangsan 3) age 4) 20 127.0.0.1:6379 lrange list1 0 -1 1) c 2) b 3) a 127.0.0.1:6379 smembers set1 1) 1 2) 2 3) 3三、DISCARD放弃事务清空队列・所有命令不执行・不生效1. 命令作用告诉 Redis 服务器我后悔了我不想执行这个事务了把事务队列里的所有命令全部清空、全部删除、全部扔掉一条都不要执行一条都不要生效2. 执行流程客户端在 Redis 命令行输入DISCARD命令发送给 Redis 服务器服务器接收到命令后直接清空当前客户端的事务队列删除所有暂存的命令服务器自动关闭事务模式恢复正常命令执行模式服务器返回OK给客户端表示事务放弃成功队列已清空。3. 完整实例# 第一步开启事务进入命令入队模式 127.0.0.1:6379 MULTI OK # 第二步发送命令存入事务队列 127.0.0.1:6379 set k1 1 QUEUED 127.0.0.1:6379 set k2 2 QUEUED 127.0.0.1:6379 set k3 3 QUEUED # 第三步放弃事务清空队列所有命令不执行 127.0.0.1:6379 DISCARD OK # 第四步验证结果所有命令都没执行key都不存在 127.0.0.1:6379 get k1 (nil) 127.0.0.1:6379 get k2 (nil) 127.0.0.1:6379 get k3 (nil)(nil)代表 key 完全不存在说明事务里的所有命令完全没有执行、完全没有生效。4. 关键注意点DISCARD只能放弃还没执行的事务还没发送EXEC命令如果已经执行了EXEC再发送DISCARD会直接报错(error) ERR DISCARD without MULTI执行DISCARD后事务模式自动关闭后续命令立即执行不再暂存。5. 错误示范已执行 EXEC 再 DISCARD直接报错127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set k1 1 QUEUED 127.0.0.1:6379 EXEC 1) OK 127.0.0.1:6379 DISCARD (error) ERR DISCARD without MULTI四、WATCH监控 Key解决并发修改错乱・Redis 简易乐观锁・最核心安全命令1. 为什么必须用 WATCH我们先看不用 WATCH两个客户端同时改同一个 key会出现什么业务问题双客户端并发场景无 WATCH数据错乱【时间 1】客户端 1 开启事务准备修改 key命令入队127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set key 100 QUEUED客户端 1 只是把命令放入事务队列还没执行EXEC还没生效【时间 2】客户端 2 直接修改 key命令立即执行、立即生效127.0.0.1:6379 set key 200 OK【时间 3】客户端 1 执行事务命令生效127.0.0.1:6379 EXEC 1) OK【最终结果】127.0.0.1:6379 get key 100错误出现了从时间先后顺序看客户端 1 先写命令 → 客户端 2 后写命令理应最终值是 200但实际结果是 100这就是并发修改导致的致命数据错误必须用WATCH命令彻底解决2. WATCH 是什么WATCH命令就是给指定的 key 加一个 **「24 小时监控哨、数据保镖」**规则只有一条在事务执行EXEC之前如果被监控的 key 被其他客户端修改过、改动过、变化过本次事务直接彻底作废、彻底失败所有命令一条都不执行、一条都不生效3. WATCH 底层原理Redis 内部给每一个存在的 key都默默维护了一个看不见、摸不着、不用你操作的版本号key 每被修改一次set、incr、del、hset 等版本号自动 1执行WATCH key时Redis 会记录当前 key 的版本号比如 0执行EXEC时Redis 自动对比「监控时的版本号」和「当前最新版本号」① 版本号完全一样 → 没人修改正常执行事务② 版本号不一样 → 被别人改过事务直接失败返回nil。4. WATCH 完整双客户端实例第一步客户端 1 监控 k1Redis 记录 k1 当前版本号 0127.0.0.1:6379 WATCH k1 OK第二步客户端 1 开启事务命令入队暂存不执行127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set k1 100 QUEUED 127.0.0.1:6379 set k2 1000 QUEUED注意只是入队还没执行还没生效第三步客户端 2 修改 k1k1 版本号从 0 自动变成 1127.0.0.1:6379 set k1 200 OK第四步客户端 1 执行事务版本号不一致事务彻底失败127.0.0.1:6379 EXEC (nil)(nil)代表事务彻底失败、彻底作废所有命令一条都没执行、一条都没生效第五步验证最终结果数据正确无错乱# k1 是客户端 2 修改的 200客户端 1 的命令完全没生效 127.0.0.1:6379 get k1 200 # k2 不存在客户端 1 的事务完全作废 127.0.0.1:6379 get k2 (nil)5. WATCH 监控多个 key 实例# 客户端1监控k1、k2两个key 127.0.0.1:6379 WATCH k1 k2 OK 127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set k1 100 QUEUED 127.0.0.1:6379 set k2 200 QUEUED # 客户端2修改k2 127.0.0.1:6379 set k2 300 OK # 客户端1执行事务失败 127.0.0.1:6379 EXEC (nil)6. WATCH 关键注意点WATCH是一次性的执行EXEC或DISCARD后监控自动取消下次需要重新 WATCH可以同时监控多个 keyWATCH k1 k2 k3 k4只要有一个 key 被改事务就失败只有其他客户端修改 key 会触发失效当前客户端事务内修改不会触发因为命令还没执行WATCH 只监控当前数据库select 0的 key跨库监控无效。五、UNWATCH取消监控解除 WATCH 的所有监控一次性清空1. 命令作用取消当前客户端对所有 key 的监控不管之前监控了多少个 key、多少组 key一次性全部解除、全部清空、全部失效2. 使用场景不想监控了重新开始事务事务执行前清空所有监控避免误触发监控错 key取消后重新监控。3. 完整实例# 监控 k1、k2、k3 三个 key 127.0.0.1:6379 WATCH k1 k2 k3 OK # 取消所有监控一次性清空 127.0.0.1:6379 UNWATCH OK # 现在其他客户端修改 k1不会影响你的事务 127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set k1 100 QUEUED 127.0.0.1:6379 EXEC 1) OK # 验证结果事务执行成功 127.0.0.1:6379 get k1 1004. 关键注意点UNWATCH 只取消当前客户端的监控不能取消其他客户端的监控没有监控任何 key 时执行 UNWATCH 不会报错返回 OKUNWATCH 执行后事务模式不受影响只是监控失效。第三节 Redis 事务的两种错误最核心决定了无回滚特性Redis 事务执行时只会出现两种错误一、错误 1入队时语法错误命令写错Redis 不认识、看不懂1. 错误场景命令拼写错误、语法错误127.0.0.1:6379 MULTI OK 127.0.0.1:6379 set k1 1 QUEUED # 命令写错sssset 不是 Redis 命令语法错误、拼写错误 127.0.0.1:6379 sssset k2 2 (error) ERR unknown command sssset 127.0.0.1:6379 EXEC # 整个事务直接作废不执行任何命令 (error) EXECABORT Transaction discarded because of previous errors.2. 最终结果绝对唯一整个事务全部作废、全部取消一条命令都不执行、一条命令都不生效二、错误 2执行时逻辑错误命令语法对但运行失败、逻辑错误1. 错误场景命令正确但是数据类型不匹配、逻辑错误127.0.0.1:6379 MULTI OK # 设置 k1 为字符串 hello正确 127.0.0.1:6379 set k1 hello QUEUED # 给字符串执行自增逻辑错误只有数字能自增 127.0.0.1:6379 incr k1 QUEUED # 设置 k2 为数字 2正确 127.0.0.1:6379 set k2 2 QUEUED # 执行事务 127.0.0.1:6379 EXEC 1) OK 2) (error) ERR value is not an integer or out of range 3) OK2. 最终结果绝对唯一无回滚错误的那一条命令失败其他命令全部正常执行、正常生效没有回滚没有恢复没有撤销k1 hello成功生效incr k1执行失败k2 2成功生效这就是Redis 没有回滚的铁证永远记住第四节 Redis 事务 30 条生产级注意事项每个客户端有独立的、专属的事务队列互不干扰、互不影响、互不冲突事务只在当前客户端生效其他客户端的命令、事务完全不受影响WATCH监控是一次性的执行EXEC/DISCARD后监控自动取消必须重新 WATCHRedis 事务绝对不能嵌套不能在事务里再执行MULTI会直接报错Redis 是单线程工作模式事务天然不会被其他命令插队、打断、插入Redis 事务不支持回滚这是 Redis 官方设计不是 bug不是故障EXEC是事务唯一执行入口不发EXEC事务永远不执行、永远不生效DISCARD只能放弃未执行的事务已经执行EXEC的事务无法撤销、无法回滚高并发场景下WATCH会导致大量事务失败不适合强并发核心业务事务中绝对不要放耗时命令如keys *、hgetall大 hash会阻塞整个 Redis事务只操作内存数据和 Redis 持久化AOF/RDB完全无关、完全分离语法错误→全事务作废逻辑错误→单条失败其他执行这是铁律开启事务后系统命令info、config直接执行不进入事务队列WATCH 监控的 key 必须在当前数据库跨库监控无效不会生效事务执行成功后队列自动清空无需手动处理、手动删除放弃事务后事务模式自动关闭后续命令立即执行不再暂存多客户端同时操作只有事务执行时会独占 Redis其他时间互不影响Redis 事务没有锁机制WATCH只是简易乐观锁不是分布式锁金融转账、支付充值、秒杀库存等严格安全场景绝对不要用 Redis 事务严格安全场景推荐使用 Redis Lua 脚本实现真正的原子性事务的唯一价值保证一组命令连续执行不被其他客户端插队、打断事务执行失败后可以编写重试逻辑最多重试 3 次避免业务失败事务中操作的 key 越多执行效率越低尽量精简事务内的命令不要在事务中执行大量命令会导致事务队列过大占用内存事务执行时间越短越好避免长时间占用 Redis 资源事务执行结果是有序列表和命令入队顺序完全一致一一对应事务中删除 key、修改 key、新增 key都不会影响事务队列事务模式下客户端断开连接事务自动放弃队列自动清空事务不支持事务内的条件判断所有命令只能按顺序执行零基础开发者优先记住Redis 事务 打包命令 一次性执行无回滚第五节 Redis 事务适用 不适用场景适合用 Redis 事务的场景批量执行多个小命令不希望被其他客户端命令打断、插队简单的并发控制用WATCH防止轻微数据错乱、逻辑错误一次性提交多个用户修改如修改昵称、头像、签名、个性介绍低并发、非核心业务追求执行效率、简单操作测试环境、开发环境快速批量执行命令简化操作不需要严格原子性、不需要回滚的简单业务逻辑一次性写入多个缓存数据保证写入连续性。不适合用 Redis 事务的场景金融转账、支付充值、提现、基金交易需要严格回滚、原子性商品库存扣减、秒杀、抢购防止超卖、少卖需要强原子性高并发核心业务WATCH频繁失败用户体验极差需要数据合法性约束的业务如余额不能为负、库存不能为负要求数据绝对一致、绝对安全、绝对严谨的核心业务多步骤、复杂逻辑、需要回滚的业务场景对数据准确性要求极高的金融、医疗、政务业务。第六节 Redis 事务常见问题1. 问Redis 事务执行失败后能不能手动回滚答不能绝对不能Redis 没有任何回滚命令也没有回滚功能如果事务执行失败只能自己手动编写补偿代码把已经执行成功的命令手动撤销Redis 完全不提供回滚能力。2. 问WATCH 监控后自己修改监控的 key事务会失败吗答不会只有其他客户端修改监控的 key事务才会失败当前客户端事务内的命令还没执行不会改变 key 的版本号所以不会触发监控失效。3. 问Redis 事务和 Lua 脚本哪个更适合生产答Lua 脚本更适合生产Lua 脚本可以实现真正的原子性、复杂逻辑、伪回滚解决 Redis 事务无回滚的缺陷是生产中原子操作的首选。4. 问事务中可以执行 get 查询命令吗答可以get 命令会进入事务队列执行后返回查询结果和修改命令一样按顺序执行。5. 问Redis 事务会占用额外内存吗答会事务队列会暂存命令命令越多、队列越大占用的内存越多所以事务内的命令要尽量精简。第七节 总结Redis 事务 命令暂存入队 一次性连续执行 不被插队这是核心本质Redis 事务唯一保证命令按顺序连续执行不被其他客户端插队、打断、插入Redis 事务没有回滚、没有原子性、没有一致性、没有隔离性、没有持久性是弱化版事务MULTI开事务 → 命令入队显 QUEUED →EXEC执行生效 /DISCARD放弃清空 →WATCH监控防并发 →UNWATCH取消全监控语法拼写错误→整个事务全部作废逻辑运行错误→单条失败其他执行WATCH 核心原理版本号对比key 被改→事务失败key 不变→事务正常严格安全、高并发、核心业务→绝对不用 Redis 事务用 Lua 脚本事务和持久化完全无关数据是否落盘看 AOF/RDB和事务一毛钱关系没有Redis 单线程 天然无并发冲突 不需要隔离级别 不需要复杂事务控制Redis 事务就是打包命令一次性跑错了不回滚简单场景用复杂场景别硬用Redis 事务不是 MySQL 事务不要用 MySQL 事务的思维理解 Redis 事务Redis 事务的唯一价值就是保证命令连续执行不被插队仅此而已结语hello 大家到这里Redis 事务从本质定义、核心命令、错误机制、生产避坑、场景选型全维度就全部讲透了全程用最接地气的 ATM 取钱、快递站入队类比把 Redis 这个「阉割版、极简版事务」的底层逻辑扒得明明白白哪怕是零基础小白也能彻底吃透、落地不踩坑。回顾全篇我们从一开始就打破了大家最容易陷入的误区Redis 事务 ≠ MySQL 标准事务这是学习 Redis 事务的第一前提也是生产中不丢数据、不踩大坑的核心底线。它没有 MySQL 引以为傲的 ACID 四大特性没有自动回滚没有严格约束没有复杂隔离级别它的本质从头到尾都很简单就是一个命令暂存队列把一组操作打包保证一次性、按顺序、不被插队地执行完仅此而已。我们再把整篇最核心、最需要刻在脑子里的知识点浓缩成几句终极总结方便你随时回顾、直接落地本质一句话Redis 事务 命令入队暂存 一次性顺序执行 不被其他客户端打断唯一保证就是「执行连续」不保证「原子回滚」命令五件套MULTI 开事务、命令入队显 QUEUED、EXEC 一键执行、DISCARD 清空放弃、WATCH 简易防并发、UNWATCH 取消监控错误铁律语法拼写错 → 整个事务直接作废逻辑运行错 → 单条命令失败其他照常执行无任何回滚WATCH 定位轻量级乐观锁靠版本号防简单并发错乱高并发场景频繁失效别当分布式锁用生产终极选型低并发非核心批量操作用事务金融支付、秒杀库存、强一致性核心业务 → 直接用 Lua 脚本别硬扛 Redis 事务。其实 Redis 之所以设计出这么「简单甚至残缺」的事务根本原因是它的定位高性能内存数据库。标准事务的回滚、隔离、锁机制都会严重拖慢 Redis 的执行效率违背了它「快、轻、简」的核心设计理念。所以它只保留了事务最基础的「打包执行」能力把更复杂的原子性、一致性需求交给了 Lua 脚本去实现。很多同学学完会觉得Redis 事务这么弱学它有什么用恰恰相反懂它的弱才懂怎么用对它。知道它不能回滚就不会在支付转账里乱用知道它不支持强并发就不会在秒杀场景硬上知道它只是批量打包命令就只会在简单批量操作里使用 —— 这才是学习 Redis 事务的真正价值认清边界不瞎用、不硬扛、不踩坑。技术学习从来不是死记硬背知识点而是理解设计初衷、掌握使用边界。本篇从理论到实操、从误区到实战、从命令到生产把 Redis 事务讲得足够细、足够透就是希望你在实际工作中面对业务需求时能快速做出正确选择让 Redis 稳定、安全、高效地服务业务。如果本篇保姆级教程对你有帮助欢迎点赞、收藏、反复回看也欢迎在评论区交流你在生产中遇到的 Redis 事务踩坑经历。后续我们还会继续拆解 RedisLua 脚本原子实战、分布式锁、高并发秒杀方案带你把 Redis 生产实战的每一个知识点都学透、落地到底。一步一个脚印打牢基础生产环境才不会掉链子。我们下篇博客见