Redis的伪事务、事务执行中三情况、不支持回滚的原因

借鉴:https://blog.csdn.net/weixin_45525272/article/details/127881229
https://blog.csdn.net/qq_42220174/article/details/99710840

一:Redis的伪事务

Redis会将一个事务中的所有命令序列化,然后按照顺序执行执行中不会被其他命令插入,不许出现加塞行为。

从严格意义上来说,redis 是没有事务的。因为事务必须具备四个特点:原子性(Atomicity),一致性(Consistency),隔离性(Isolation),持久性(Durability)。然后 redis 是做不到这四点,只是具备其中一些特征,redis的事务是个伪事务,而且不支持回滚

伪事务的两种体现方式:multi+exec命令、lua脚本

二:事务执行中三情况(错误处理)

1.命令入队报错 :事务里面的命令全部执行失败

在事务提交之前,客户端执行的命令缓存(队列)失败,比如命令的语法错误(命令参数个数错误,不支持的命令等等)。如果发生这种类型的错误,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"

2.命令执行报错:报错的命令执行失败,其他的命令正常执行

事务提交后开始顺序执行命令,之前缓存在队列中的命令有可能执行失败。命令正确,类型不正确这种,报错的命令执行失败,其他的命令正常执行(包括报错之后的命令)。

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"

3.乐观锁导致失效(watch命令) :事务中修改 watch监控的key,不会生效

watch 监控 key 所起的作用实际上是一个乐观锁,它所监控的是在事务期间有没有其他客户端对所监控的值进行修改

# 客户端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"

三:不支持回滚的原因

1.Redis 内部设计推崇简单和高性能,支持事务回滚能力会导致设计复杂,这与Redis的初衷相违背,因此不需要回滚能力
2.Redis 的应用场景明显不是为了数据存储的高可靠与强一致性而设计的,而是为了数据访问的高性能而设计,设计者为了简单性和高性能而部分放弃了原子性。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值