前言
hello 小伙伴们,晚上好啊!
分布式锁是八股文里面重点,也是难点,对于没有做过高并发项目的小伙伴来说,想学习但没有实践机会。这都不是问题,学起来再说,今天跟着我的思维走,我们一起看看分布式锁中锁过期解决方案,就当做项目啦。
常规扣库存流程
1、加分布式锁
2、扣库存逻辑
3、解分布式锁
很简单,很安全,很清晰,且有漏洞
漏洞-锁过期
0、如果a持有锁,但a执行同步代码时,没有cpu时间片
1、redis key过期
2、b争夺到锁
3、a获得时间片
完了,同步代码同时有两个线程在工作,原子性被破坏,一致性也没保住。怎么解呢?
可以用悲观锁包住乐观锁的思想,做一些兜底。
用一个大的乐观锁包住同步代码块,就算ab并行执行,也不会出现一致性问题,同时性能上也有保证。为什么特意强调性能,因为跟看门狗粗暴的延长锁时间相比,这套方案性能上肯定是比看门狗强的多。
且听我细细道来。
性能提升
假设扣库存耗时30ms,锁过期时间100ms,看门狗续命100ms。a执行了10ms,失去cpu时间片,随着时间推移,假设到了第90ms,看门狗开始续命,然后到第180ms,a获得cpu时间片,第200ms,a unlokc。在这200ms里,a执行了30ms,阻塞170ms,这170ms里,可以完成接近6次扣库存。 如果采用乐观锁的方案,则不续命,a阻塞区间,其他线程正常争夺锁,执行业务逻辑。
快照读还是当前读
在查stock1的时候,sql也有讲究。如果选择select for update,则整行加锁,且是悲观锁,效果跟看门一样。所以这里只能用快着读,如果你的cas要自旋,就得考虑readView问题,把隔离级别降为rc,每次读都是最新的readView。
总结
你知道的越多,你知道的越少。