Redis事务失效的三种场景
文章目录
Redis 事务失效的三种场景
Redis事务失败,有三种类型的失败场景:
命令入队报错
在事务提交之前,客户端执行的命令缓存(队列)失败,比如命令的语法错误(命令参数个数错误,不支持的命令等等)。
如果发生这种类型的错误,Redis将向客户端返回包含错误提示信息的响应,同时Redis会清空队列中的命令并取消事务。
示例代码如下,开启一个客户端:
127.0.0.1:6379> set name mengmeng # 事务之前执行 OK 127.0.0.1:6379> multi # 开启事务 OK 127.0.0.1:6379> set name qianqian # 事务中执行,命令入队列 QUEUED 127.0.0.1:6379> setset name qianqian2 # 错误的命令,模拟失败场景 (error) ERR unknown command `setset`, with args beginning with: `name`, `qianqian2`, 127.0.0.1:6379> exec # 提交事务,发现由于上条命令的错误导致事务已经自动取消了 (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379> 127.0.0.1:6379> 127.0.0.1:6379> get name # 查询name,发现未被修改 "mengmeng"
最后发现事务里语句失效
命令执行报错
事务提交后开始顺序执行命令,之前缓存在队列中的命令有可能执行失败。
示例代码如下,开启一个客户端:
127.0.0.1:6379> multi # 开启事务 OK 127.0.0.1:6379> set name mengmeng # 设置名字 QUEUED 127.0.0.1:6379> set age 18 # 设置年龄 QUEUED 127.0.0.1:6379> lpush age 20 # 此处仅检查是否有语法错误,不会真正执行 QUEUED 127.0.0.1:6379> exec # 提交事务后开始顺序执行命令,第三条命令执行失败 1) OK 2) OK 3) (error) WRONGTYPE Operation against a key holding the wrong kind of value 127.0.0.1:6379> get name # 第三条命令失败没有将前两条命令回滚 "mengmeng"
最后发现事务里语句失效
乐观锁导致失效
由于乐观锁失败,事务提交时将丢弃之前缓存的所有命令序列。
watch 监控 key 所起的作用实际上是一个乐观锁,它所监控的是在事务期间有没有其他客户端对所监控的值进行修改
在Redis中可以通过开启两个redis客户端并结合watch命令模拟这种失败场景。
示例代码如下,开启两个客户端:
# 客户端1 127.0.0.1:6379> set name mengmeng # 客户端1设置name OK 127.0.0.1:6379> watch name # 客户端1通过watch命令给name加乐观锁 OK # 客户端2 127.0.0.1:6379> get name # 客户端2查询name "mengmeng" 127.0.0.1:6379> set name qianqian # 客户端2修改name值 OK # 客户端1 127.0.0.1:6379> multi # 客户端1开启事务 OK 127.0.0.1:6379> set name lili # 客户端1修改name QUEUED 127.0.0.1:6379> exec # 客户端1提交事务,返回空 (nil) 127.0.0.1:6379> get name # 客户端1查询name,发现name没有被修改为lili "qianqian"