王道革 2020-07-05
悲观锁:
很悲观、认为什么时候都会出问题、无论做什么都加锁、很影响性能
乐观锁:
1.很乐观、认为什么时候都不会出问题、所以不上锁。更新数据的时候去判断下,在此期间是否有人修改这个数据。
2.获取version
3.更新时比较version
watch (监控、实现乐观锁)
监控测试、正常执行:
my-redis:0>set money 100 ########## 设置余额 100 元 OK my-redis:0>set out 0 ####### 设置花费 0 元 OK my-redis:0>watch money ##### watch 监控 余额 OK my-redis:0>multi ########## 开启事务 OK my-redis:0>decrby money 20 ####### 余额 -20 QUEUED my-redis:0>incrby out 20 ######## 花费 +20 QUEUED my-redis:0>exec ######## 执行事务 80 20 my-redis:0>get money ############ 正常 !数据期间没有发生变动,这个时候就正常执行成功 80 my-redis:0>
测试多线程修复值、使用乐观锁操作。(事务没执行、执行前另一个线程改了余额、监控的值发生变化、这时执行事务会失败)
my-redis:0>get money #### 获取到余额是80 80 my-redis:0>watch money ##### 监控余额 OK my-redis:0>multi #######开启事务 (这时候另一个线程把余额改成1000) OK my-redis:0>decrby money 10 ########余额-10 QUEUED my-redis:0>incrby out 10 ########### 花费+10 QUEUED my-redis:0>exec ######### 执行事务失败,因为监控的余额在执行之前已经被改了 null
怎么解决:在事务执行失败后,解锁 unwatch ,2.再重新获取锁,执行 提交
my-redis:0>unwatch #########解锁 OK my-redis:0>watch money ######重新获取锁 监控 OK my-redis:0>multi ########开启事务 OK my-redis:0>decrby money 10 QUEUED my-redis:0>incrby out 10 QUEUED my-redis:0>exec #########执行成功 990 30