Redis的事务

首先说明一点:
Redis中的事务不能回滚,也就是说有五个命令,最后一个执行失败了,前四个依然是执行成功的。

大家可以思考一下,为什么Redis不支持事务呢?
1.因为Redis设计的目的就是为了高性能,如果支持事务,就比较影响性能(比如就像mysql一样,会记录redo,undo日志),这种写磁盘对性能影响较大。
2.Redis的命令都是有编译检查的,也就是说如果你命令错了,输入命令后就会提示错误,就进不到事务执行的步骤,能规避掉大多数情况的错误

下面介绍一下Redis事务的实现

Redis实现事务是用一个队列将多个命令保存起来,输入exec命令时,再从队列中取出命令,依次执行(FIFO,先进先出)。
Redis实现事务的几个命令:
multi , exec , discard , watch , unwatch

  • multi:开启redis事务,后面输入的命令就会放入队列中
  • exec:执行事务,依次取出队列中的命令执行
  • discard:清空当前队列里的命令
  • watch:监视莫些key对应的值是否有变化
1.先来证明一下Redis中的事务不能回滚:

在这里插入图片描述
看图片(开启事务后执行命令返回的是QUEUE,这也说明了命令被放入了队列中):
1.先用multi开启事务,然后输入了三个命令;
2.由于第三个命令 key=aaa 已经设置为了string类型,这里故意再次把它设为hash类型,执行时会报错;
3.最后执行exec命令提交事务,从结果可以看出,前两个执行成功了,第三个命令执行失败没有导致前面两个命令回滚

2.下面我们以一个例子再来看看watch的作用

在这里插入图片描述
还有一个步骤是:再打开一个客户端,在multi之后,exec之前执行了命令

set ccc 666

解释一下上面的图片:
1.先用watch监视key=ccc 的值的变化;
2.然后用multi开启事务,接着输入了三个set命令;在这期间另外一个客户端调用set ccc 666 修改了key=ccc的值;
3.然后调用exec提交事务;由于watch监控的key=ccc的值变化了,所以事务提交失败,也就是一个命令都没执行
4.最后,去get zzz,返回nil,说明事务没有执行。

3.下面简单说一下watch的底层实现

① 在调用watch监视key时(可多个key),Redis会采用字典(hash)将监控信息存起来<监视的key,监视的客户端>,一个key可能会有多个客户端监视。
② 在监视的key的值被修改后,会触发打开一个标识REDIS_DIRTY_CAS,服务端在收到客户端事务提交请求后,会去检查这个标识是否打开,如果已经打开了,服务端会认为事务已经不安全,拒绝执行事务。

参考:<<Redis的设计与实现>>

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值