远程字典服务 — Redis 札记(十:watch 监视锁 面试高频)

Redis 监视 Watch

悲观锁:

  • 认为什么时候都会出现问题,无论做什么都要加锁

乐观锁:

  • 认为什么时候都不会出现问题,所以不会加锁,更新数据的时候去判断一下,在此期间是否有人修改过这个数据
  • 获取Version版本
  • 更新的时候比较Version是否发生修改

命令

命令解释
unwatch取消 watch 命令对所有 key 的监视。
watch key [key …]监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断

测试

正常执行情况

监视 name 对象,如果该对象在监视期间没有发生变动,这个事务就可以正常执行 !

127.0.0.1:6379> set name csnz
OK
127.0.0.1:6379> get name
"csnz"
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> set name CSNZ
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> exec
1) "csnz"
2) OK
3) "CSNZ"

多线程修改值,使用watch当做redis的乐观锁

线程一:


127.0.0.1:6379> set name csnz
OK
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> set name CSNZ
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED

此时线程一还没执行事务

新开一个线程作为线程二 、执行如下语句

127.0.0.1:6379> get name
"csnz"
127.0.0.1:6379> set name csnz666
OK

此时线程二 修改了name的值

线程一 在线程二修改值 之后 打算执行事务 发现…

127.0.0.1:6379(TX)> exec
(nil)

在线程一 执行 exec 提交事务之前,另外有线程修改了name值,此时会导致线程一事务执行失败 !

监视之后事务失败情况

  1. 当发现事务执行失败时,就先解锁
  2. 获取最新的锁,再次进行监视,相当于更新Version版本号
  3. 最后exec 再比对监视的值是否发生了变化,如果没有被修改,那么可以执行成功,否则继续执行失败 !

127.0.0.1:6379> set name csnz
OK
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> set name CSNZ
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> exec
(nil)
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> watch name
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> set name CSNZ
QUEUED
127.0.0.1:6379(TX)> get name
QUEUED
127.0.0.1:6379(TX)> exec
1) "csnz666"
2) OK
3) "CSNZ"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值