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事务失效的三种场景的主要内容,如果未能解决你的问题,请参考以下文章

微服务异常的三种场景和处理方法

「Spring」事务失效的场景

Spring 事务失效的7种场景

Redis集群部署的三种模式

Redis 实现限流的三种方式

使得httpsession失效的三种方式是