Redis事务

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

一、Redis事务核心定义

Redis事务是Redis提供的批量命令串行执行机制,本质是将多个独立命令打包存入命令队列,通过专属命令触发队列一次性执行,全程不被其他客户端命令插队,实现命令组的隔离执行。

不同于关系型数据库的强事务,Redis事务设计偏向轻量级、高性能,核心目标是保证命令执行的顺序性和隔离性,而非严格的ACID特性,这也是Redis保持高吞吐的关键设计之一。

二、Redis事务核心特性

  • 串行执行与隔离性:事务内所有命令会被序列化,按入队顺序依次执行,执行期间其他客户端的请求无法插入,彻底避免并发命令干扰,保证事务操作的独立性。
  • 弱原子性:事务要么全部入队、要么全部触发执行,但不支持命令执行失败后的回滚,这是Redis事务与传统数据库事务最核心的区别。
  • 命令延迟执行:开启事务后,后续命令不会立即落地执行,而是暂存到客户端事务队列,仅返回QUEUED状态标识,直到触发执行命令才统一处理。
  • 无持久性保障:Redis事务执行依赖内存操作,事务完成后数据是否持久化,取决于Redis的持久化策略(RDB/AOF),事务本身不强制保证数据落盘。

三、Redis事务核心命令详解

Redis事务围绕5个核心命令实现全生命周期管控,每个命令各司其职,配合完成事务开启、入队、执行、取消、监控操作。

1. MULTI:开启事务

用于标记事务块的起始,执行后客户端进入事务上下文,后续所有读写命令都会被加入事务队列,而非立即执行,命令固定返回OK

> MULTI
OK
    

2. 普通命令:入队事务

MULTI之后执行的Redis命令(如SET、GET、INCR等),不会立即生效,仅返回QUEUED表示已加入队列,所有命令按输入顺序暂存,等待最终触发。


> SET name redis
QUEUED
> INCR count
QUEUED
    

3. EXEC:执行事务

触发事务队列中所有命令的批量执行,按入队顺序依次运行,返回每个命令的执行结果数组;若事务被取消(DISCARD)或键被篡改(WATCH失效),则返回nil。


> EXEC
1) OK
2) (integer) 1
    

4. DISCARD:取消事务

清空当前事务队列的所有命令,退出事务上下文,客户端恢复普通命令执行模式,固定返回OK


> DISCARD
OK
    

5. WATCH/UNWATCH:乐观锁监控

WATCH用于监控指定键的变化,在EXEC执行前,若被监控键被其他客户端修改,当前事务会直接放弃执行(EXEC返回nil),实现高并发下的数据一致性;UNWATCH用于取消所有键的监控。


> WATCH balance
OK
> MULTI
OK
> DECRBY balance 100
QUEUED
> EXEC
(nil)  # 若balance被其他客户端修改,事务执行失败
    

四、Redis事务完整执行流程

  1. 开启事务:客户端执行MULTI,Redis标记当前连接进入事务模式。
  2. 命令入队:客户端发送业务命令,Redis校验语法合法性,合法则加入队列返回QUEUED,语法错误直接标记事务为失败状态。
  3. 触发/取消事务:客户端执行EXEC则批量执行队列命令;执行DISCARD则清空队列,终止事务。
  4. 结果返回:EXEC执行完毕后,按命令顺序返回每个命令的执行结果,事务结束,客户端恢复普通模式。

五、Redis事务异常处理机制

1. 语法错误(入队阶段)

若命令存在语法错误(如命令名写错、参数不匹配),Redis会直接标记事务为无效状态,后续EXEC执行时会直接拒绝运行整个事务,所有命令都不生效。

2. 运行时错误(执行阶段)

若命令语法合法,但执行时出现逻辑错误(如对字符串执行INCR操作),Redis不会终止事务,会继续执行队列中后续命令,仅报错当前命令,这也是Redis无回滚机制的核心体现。

重点:Redis不支持事务回滚,官方认为这种设计能提升事务执行性能,且开发阶段可规避大部分运行时错误,无需依赖数据库回滚兜底。

六、Redis事务与关系型数据库事务对比

原子性

弱原子性,仅保证命令批量执行,不回滚

强原子性,要么全成功,要么全回滚

隔离级别

仅实现串行化隔离,无其他隔离级别

支持读未提交、读已提交、可重复读、串行化

锁机制

乐观锁(WATCH),无悲观锁

支持悲观锁、乐观锁多种机制

性能

极高,轻量级队列执行,无额外开销

较低,需维护事务日志、锁、回滚段

适用场景

高并发、简单批量操作、无强一致性要求

金融交易、订单结算等强一致性场景

七、Redis事务实战避坑指南

  • 禁止在事务中使用阻塞命令:如BLPOP、SUBSCRIBE等,会导致事务队列阻塞,影响Redis整体性能。
  • WATCH需配合重试机制:高并发下WATCH失效概率高,需在应用层添加重试逻辑,保证业务最终执行。
  • 控制事务命令数量:事务队列过长会占用Redis内存,且批量执行时会阻塞其他请求,建议拆分大事务。
  • 集群模式慎用事务:Redis集群不支持跨槽位事务,仅能操作同一槽位的键,多键操作需确保哈希槽一致。
  • 区分语法错误和运行时错误:提前校验命令合法性,避免运行时错误导致部分命令生效、部分失败。

ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花

Redis基础 文章被收录于专栏

本专栏带你从零掌握 Redis 核心知识,清晰讲解过期策略、内存淘汰等面试重点。用通俗语言拆解底层原理,搭配实战案例与常见问题总结,兼顾入门理解与面试备考,帮你快速建立完整 Redis 知识体系,轻松应对开发与面试

全部评论
可以加个 tag 的,不加标签不会推流
点赞 回复 分享
发布于 03-19 17:00 湖北

相关推荐

一、开场与项目基础先做个自我介绍。为什么用消息订阅异步落库,而不是同步写库?系统峰值大概在什么级别?有考虑过为什么库支撑不了吗?二、消息队列可靠性MQ 写失败了,怎么保证消息不丢?是先批量更新数据库,再写推送状态吗?先更新数据库再推送?如果推送状态写失败了会怎么办?可以支持重试吗?如果更新成功、推送也成功,重试一次会怎么样?会推两条吗?三、分布式锁项目里用的分布式锁具体怎么实现?锁是怎么释放的?锁过期时间设 30 天,30 天内重试会有什么问题?正常用 Redis 实现防并发的分布式锁,应该怎么实现?释放锁在哪里释放?正常请求结束后,在哪个环节释放锁?四、MySQL 优化线上一条 SQL 执行 5 秒,怎么优化?这 4 种 SQL case,哪些能命中索引,哪些命中不了?知道什么是 ICP 优化吗?五、高并发:商品超卖活动限量 100 件,说出三种防止超卖的方案,并对比优缺点。详细说下 Redis + DB 这种方案,怎么保证 Redis 和 DB 的一致性?这种方案和第二种 Redis + MQ 方案有区别吗?Redis + MQ 方式下,怎么保证 Redis 和 DB 的数据一致性?比如 Redis 扣减成功、MQ 写失败怎么办?如果加入对账机制,对账需要哪些数据?上游、下游分别要存哪些数据?六、大数据量分页与分库分表订单表 5000 万数据,分页查询怎么优化?订单表达到 1 亿条,单表查询越来越慢,怎么处理?水平分表具体怎么分?用户订单表,根据什么字段切分比较合适?七、数据库死锁数据库死锁产生的原因是什么?怎么避免?生产或日常开发中有没有遇到过死锁问题?八、Redis 缓存问题什么是缓存雪崩、缓存穿透、缓存击穿?分别怎么解决?九、缓存更新策略先更新数据库还是先更新 / 删除缓存?方案是什么?先更新 DB 再删缓存,那什么时候写缓存?十、限流方案实现严格一分钟内的请求限流,用 Redis 怎么做?还有其他限流方法吗?滑动窗口(ZSET)、令牌桶、漏桶这几种方案有什么区别?适用场景分别是什么?十一、前端基础前端平时有接触吗?比如 JS?什么是跨域?为什么会有跨域?怎么解决?了解 CSRF 攻击吗?怎么防御?防 CSRF 的 Token 怎么生成?十二、分布式事务了解什么是分布式事务吗?说一下两阶段提交。十三、算法题完成两道算法题,并讲解代码思路。十四、AI 工具与 Agent日常开发用过哪些 AI 工具?豆包帮你解决了什么问题?Cursor 是付费会员吗?怎么付费?AI 生成的代码怎么验证正确性?让 AI 写一个 Redis 分布式锁工具类,你会怎么描述需求、怎么写 Prompt?系统客服角色接入大模型做智能问答,整体架构和流程怎么设计?RAG 的整体流程是什么?一份文档怎么向量化接入?向量检索后,是把所有相关 wiki 都交给大模型吗?检索出的内容做精简压缩用什么实现?什么是 AI Agent?和普通写 Prompt 有什么区别?
点赞 评论 收藏
分享
评论
1
2
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务