Redis-05-乐观锁

Redis-05-乐观锁

1. 悲观锁

  • 很悲观,什么时候都会出问题,无论做什么都会加锁

2. 乐观锁

  • 很乐观,认为什么时候都不会出现问题,所以不会上锁
  • 更新数据的时候判断一下,在此期间是否有人修改过这个数据 (mysql–version)

3. 监控-Watch

面试常问!!! – 》 Watch实现乐观锁

正常执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
127.0.0.1:6379> set money 100
OK
127.0.0.1:6379> set out 0
OK
127.0.0.1:6379> watch money ## 监视money对象
OK
127.0.0.1:6379> multi ## 事务正常结束,数据期间没有发生变动,这个时候正常成功
OK
127.0.0.1:6379> decrby money 20
QUEUED
127.0.0.1:6379> INCRBY out 20
QUEUED
127.0.0.1:6379> exec
1) (integer) 80
2) (integer) 20

测试多线程修改值,使用watch可以当做redis乐观锁操作!

1
2
3
4
5
6
7
8
9
### 线程1
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> INCRBY out 10
QUEUED
1
2
3
4
5
### 线程2 
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> set money 1000
OK

结果:

1
2
3
4
5
6
7
8
9
10
11
### 线程1
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec ### 执行之前,另外一个线程修改了值,就会导致事务执行失败
(nil)

解决问题:

若果修改失败,获取最新的值就好

1
2
3
4
5
6
7
8
9
10
11
12
13
127.0.0.1:6379> UNWATCH  ## 1. 解锁
OK
127.0.0.1:6379> watch money ## 2. 重新获取锁
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby money 1
QUEUED
127.0.0.1:6379> INCRBY out 1
QUEUED
127.0.0.1:6379> exec ## 3. 执行(比对监视的值是否发生了变化,如果没有变化,那么可以执行成功,如果变化了就执行失败)
1) (integer) 999
2) (integer) 1000
打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!
  • © 2019-2022 Zhuuu
  • PV: UV:

请我喝杯咖啡吧~

支付宝
微信