决战圣地玛丽乔亚Day50--Redis实现分布式锁

分布式锁的最简单版本: setnx key  value

set key value 命令是对key设置值的命令,不管key是否存在值都会设置进去。

setnx  key value命令对key进行值的设置前进行非空判断,如果key有值返回0,如果key为空就设置返回1.

在setnx失败后会循环等待锁的释放:

 

缺点:没有对超时进行限制,如果在delete之前进行宕机,那么锁永远不会释放出去,那么就一直超时等待。

 

升级版本:给key设置一个超时时间

set key value ex 多少秒  nx

 

 nx 表示该set命令具备setnx的特性。

如:set key eminent ex 60 nx     对key  eminent设置60s过期时间,具备setnx特性

 

但是会出现一个问题,设置的60s内,如果业务流程较长的情况下,超出了60s。线程A释放key后,线程B获取了分布式锁执行任务。当线程A业务流程走完后删除锁

删除的是线程B的锁。锁的获取和删除都是通过锁的名称来进行分辨,所以在此基础上,我们需要加一个线程判断:

我们可以把set key eminent ex 60 nx 命令的锁的名称设置为当前线程的唯一标识,这样我们在删除的时候,对锁的名称进行一次判断即可解决这个问题。

业务逻辑执行超时的情况下:

 

 新的问题是:

判断锁是否是当前线程和释放锁的操作不是原子性操作。就可能会导致,判断完确定释放后进行卡顿,卡顿期间线程B获取锁,恢复卡顿后,删除的是别的线程的锁。

 

 

最终版本:通过Lua脚本保证判断线程和执行操作的原子性。

 

 

我们可以通过Lua脚本在加锁的时候解决不可重入的问题。

在Lua脚本中先判断锁(key)是否存在,如果存在则再判断持有这把锁的线程是否是当前线程,如果不是则加锁失败,否则当前线程再次持有这把锁,并把锁的重入次数+1。在释放锁时,也是先判断持有锁的线程是否是当前线程,如果是则将锁的重入次数-1,直至重入次数减至0,即可删除该锁(key)。 

 

 

posted @   NobodyHero  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示