watch 命令
redis使用watch命令来实现乐观锁的操作。
首先,我们先来看一下单个线程情况下,加上乐观锁,正常执行事务的情况:
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 #开启事务,money对象在事务执行过程中没有变更,事务正常执行。
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
接下来,我们开启另一个线程,在之前的线程执行事务之前,对money对象的进行更改,来看一看对money上的锁机制是否生效:
##线程1
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
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> ......
此时线程1,只是开启了事务,在这个过程中还没有执行事务的操作
##线程2
127.0.0.1:6379> incrby money 20
(integer) 120
此时线程2,进入redis数据库,更改了money对象的值
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
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
(nil)
之后我们在线程1中执行之前的事务操作,发现最终操作失败,也就是说加在money对象上的乐观锁生效了。
我们如果想取消乐观锁可以使用 unwatch
命令
127.0.0.1:6379> unwatch
OK