悲观锁
- 认为什么时候都会出问题,无论做什么都加锁;
乐观锁
- 认为什么时候都不会出问题,所以不会加锁;在更新数据的时候判断一下在此期间是否有人改动了此数据;
- 获取version
- 更新数据的时候比较version
正常情况
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> incrby out 10
QUEUED
127.0.0.1:6379> decrby money 10 #访问money时检查到money没有发生改变,事务正常执行
QUEUED
127.0.0.1:6379> exec
1) (integer) 10
2) (integer) 90
不正常情况
线程一
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> incrby out 10
QUEUED
127.0.0.1:6379> decrby money 10
QUEUED
在执行exec前在线程二上修改money的值,会导致事务执行失败
127.0.0.1:6379> exec
(nil)
线程二
127.0.0.1:6379> set money 1000
OK
测试多线程修改值,使用watch当作redis的乐观锁操作
127.0.0.1:6379> unwatch #事务执行失败,先解锁
OK
127.0.0.1:6379> watch money #加锁,获取最新版本的money
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby out 10
QUEUED
127.0.0.1:6379> decrby money 10
QUEUED
127.0.0.1:6379> exec
1) (integer) 10
2) (integer) 990