十、redis 入门 之 redis事务
一、概述
Redis 事务是一组命令的有序集合,能保证命令串行化执行(不被其他命令插入)
1、核心概念
- 本质:把多个命令打包,按顺序依次执行,执行期间不会被其他客户端命令 “插队”,实现简单的操作原子性(注意:Redis 事务并非严格数据库事务,不支持回滚,失败需业务自行处理 )。
2、常用命令与流程
multi
:开启事务,后续输入的命令会进入事务队列暂存,不立即执行。exec
:提交事务,执行队列中所有暂存的命令,一次性批量执行。discard
:放弃事务,清空队列,终止未提交的事务。watch
:监视 1 个或多个 key,若事务执行前这些 key 被其他操作修改,事务会被打断(exec
返回空,不执行队列命令 ),用于实现 “乐观锁” 逻辑。
3、特性
1.原子性:Redis事务保证的是队列中的命令作为一个整体要要么全部执行,要么全部不执
行。但是,如果事务中的某个命令因为执行错误而失败,Redis会米续执行事务中的其
他命令,而不是回滚整个事务。
2.无隔离级别:Redis事务中的命令在提交前不会被实际执行,因此不存在传统数据库中
的事务隔离级别问题,如脏读、不可重复读或幻读。
3.命令队列:当客户端发送multi命令后,所有随后的命令都会被放入一个队列中,而
不是立即执行。当exec命令被发送时,Redis会尝试执行队列中的所有命令。
4.乐观锁:Redis使用watch命令来实现乐观锁机制。客户端可以监控一个或多个键,
如果在执行exec之前这些键的值被其他客户端改变,事务将不会拼啊。
5.自动放弃:如果事务因为监控键被修改而不能执行,exec命令将放弃当前队列命令,
返回null。
6.discard命令:如果客户端在发送multi之后决定放弃事务,可以使用discard命令
来清空事务队列并退出事务状态。
7.有限的回滚:Redis事务不支持命令级别的回滚。如果事务各中的某个命令失败,Redis
会停止执行后续命令,而不是回滚到事务开始前的状态。
二、执行
1、命令语法错误(如参数数量不对)→ 事务整体不执行
开启事务后,输入语法错误的命令(如 getset key
少传参数),执行 exec
时事务会整体放弃,所有命令都不执行。
入队命令时关注 QUEUED
反馈,若出现错误提示,立即用 discard
放弃事务,避免无效等待。
2、命令逻辑错误(如对字符串执行 incr
)→ 部分执行、无自动回滚
命令语法正确但逻辑错误(如对字符串 key2="abc"
执行 incr
),exec
时错误命令跳过,其他正确命令仍执行,事务不回滚。
解决办法
- 业务层提前校验数据类型 / 状态(如执行
incr
前先查type key
确认是整数); - 事务执行后检查结果,若有错误,手动回滚已执行的正确命令。
3、并发修改冲突(多客户端改同一 key)→ 事务被打断
客户端 A 用 watch
监视 balance
,开启事务准备修改;客户端 B 在 A 提交事务前修改了 balance
,导致 A 的事务 exec
返回 nil
,无法执行。
解决办法
用 watch
实现乐观锁,exec
失败后重新查询最新数据,再次发起事务(重试逻辑)。
4、需主动放弃未提交事务(如业务逻辑取消)
开启事务并入队命令后,因业务逻辑变化(如用户取消订单),需终止事务,不执行队列命令。
解决办法
执行 discard
清空事务队列,放弃所有暂存命令。