Redis事务失效的三种场景
Posted 杨 戬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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"
以上是关于Redis事务失效的三种场景的主要内容,如果未能解决你的问题,请参考以下文章