REDIS_04Redis高并发分布式锁
2023-04-26 23:44:15 6 举报
AI智能生成
Redis高并发分布式锁
作者其他创作
大纲/内容
秒杀活动中,用户在购买前判断库存是否充足,然后购买成功后会减掉库存
场景
在单机环境下运行,一个执行完了下一个再执行,这样不会有问题
单机场景
并发环境下,在未加锁的情况下多线程查出来的库存量是一样的,后面继续执行,到最后会发现有两个请求购买成功了,但是库存只减了1,这样就会出现超卖的问题
并发场景
将 key 的值设为 value,若给定的 key 已经存在,则 SETNX 不做任何动作
setnx key value
返回(integer) 0
EXISTS job # job这个key不存在
(integer) 1
SETNX job \"programmer\" # 设置job
(integer) 0
SETNX job \"programmer2\" # 重新设置job,失败
\"programmer\"
GET job # job还是第一次设置的值
使用方法
根据setnx的结果来判断是否是获取到锁,是就执行减库存的操作,不是则返回网络错误
try…finally来解决
当在执行删除key的操作前,程序异常退出了,后面的请求永远不会执行到减库存的逻辑
等到过期时间到后key就会被redis销毁掉,不会影响其他的请求
设置过期时间的代码和设置锁值的代码应该使用原子性来执行
除了程序异常退出,还可能机器宕机,这样异常就捕获不到了,这是就需要给key设置一个过期时间
当前请求1的处理库存逻辑需要12秒,还没执行完,锁就失效了
请求2获得了锁后,开始处理逻辑,请求2执行了2秒后,请求1处理完毕,删除了锁,但是这个锁是请求2的锁
请求3,不等到请求2释放锁,在第12秒时就可以获得锁
然后请求2会会再把请求3的锁提前释放掉
针对这种问题,我们需要对判断要删除的锁是不是自己创建的
子主题
考虑在加了超时的情况下,业务还没执行完,但锁超时间已到
使用思路
setnx
redisson提供了不同类型redis部署的连接方案
//拿到锁对象RLock redissonLock=redisson.getLock(couponKey);
获得redisson锁
加锁(同时实现加锁,看门狗锁续命的功能)
//解锁redissonLock.unlock();
释放锁
让后面的线程无法删除前面线程
如果业务代码在无异常,并且仍然在执行的情况下,我们加一个可以自动将锁时间延长的功能
锁续命
考虑到业务时间比超时时间长,考虑可以给锁续命的问题
释放锁的时候,如果出现异常续命任务还会继续执行
释放锁如何保持原子性
redisson
分布式锁
Redis高并发分布式锁
0 条评论
回复 删除
下一页