悲观锁
- 很悲观,认为什么时候都会出问题,无论做什么都会加锁!很耗性能
乐观锁
- 很乐观,认为什么时候都不会出问题,所以不会上锁!更新数据的时候去判断一下,在此期间是否有人修改过这个数据
- 获取version
- 更新的时候比较version
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 #事务正常结束,数据期间没有发生变动,这个时候就正常执行成功!
OK
127.0.0.1:6379(TX)> decrby money 20
QUEUED
127.0.0.1:6379(TX)> incrby out 20
QUEUED
127.0.0.1:6379(TX)> exec
1) (integer) 80
2) (integer) 20
测试多线程修改值,使用watch可以当做redis的乐观锁操作!
- redis-client1
127.0.0.1:6379> watch money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 10
QUEUED
127.0.0.1:6379(TX)> incrby out 10
QUEUED
此时redis-client1还没执行事务,另一个客户端将money的值改了
- redis-client2
127.0.0.1:6379> get money
"80"
127.0.0.1:6379> set money 1000
OK
- 然后redis-client1执行事务
127.0.0.1:6379(TX)> exec #执行之前,另外一个线程,修改了money的值,这个时候,就会导致事务执行失败
此时watch监听到money发生了修改变化,会导致该事务执行失败!
如果修改失败,获取最新的值就好
127.0.0.1:6379> get money
"1000"
127.0.0.1:6379> get out
"20"
127.0.0.1:6379> unwatch #1,如果发现事务执行失败,就先解锁
OK
127.0.0.1:6379> watch money #2,获取最新的值,再次监听,select version
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379(TX)> decrby money 10
QUEUED
127.0.0.1:6379(TX)> incrby out 10
QUEUED
127.0.0.1:6379(TX)> exec #3,比对监视的值是否发生了变化,如果没有变化,那么可以执行成功,如果变化了就执行失败
1) (integer) 990
2) (integer) 30