七:redis锁
监控!watch(redis乐观锁就是通过watch来实现的,面试常问)
悲观锁:
- 认为无论何时都可能出现问题,无论做什么都会加锁!
乐观锁:
- 认为无论什么时候都不会出现问题,所以不会上锁!更新数据时会去判断一下在此期间是否修改过这个数据
- 获取version
- 更新时比较version
redis监视测试
正常执行:
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 10
QUEUED
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> exec #事务正常执行,数据在事务执行期间没有发生变动,这时就正常执行成功!
1) (integer) 90
2) (integer) 10
多线程并发修改时,使用watch可以当作redis的乐观锁操作:
#主线程
127.0.0.1:6379> watch money #监视 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 #执行之前,另外一个线程修改了money值,这个时候就会导致事务执行失败
(nil)
#另外一个线程
127.0.0.1:6379> set money 1000
OK
取消监视命令:unwatch,但执行exec后不管是否成功都会自动取消监视
如果修改失败,重新监视money,再执行事务即可:
127.0.0.1:6379> watch money #再次监视最新值,及监视对应version
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 #比对监视值是否变化,未变则执行成功,变了则执行失败!
1) (integer) 990
2) (integer) 20