分布式锁(设置锁和过期时间)
问题描述:
随着业务发展的需要,原单体单机部署的系统被演化分成分布式集群系统后,由于分布式系统多线程、多进程且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题
分布式锁主流的实现方案:
1、基于数据库实现分布式锁
2、基于缓存(Redis等)
3、基于Zookeeper
每一种分布式锁解决方案都有各自的优缺点。
解决方案:基于Redis实现分布式锁
redis:命令
# set sku:1:info "OK" NX PX 10000
EX second:设置键的过期时间为seconds秒,SET key value EX second效果等同于SETEX key second value
NX::只在键不存在时,才对键进行设置操作,SET key value NX效果等同于SETNX key value
XX:只在键已经存在时,才对键进行设置操作
DEL:释放锁
设置过期时间解决锁一直不能释放的问题
上锁之后出现异常无法设置过期时间:上锁时同时设置过期时间 set users 10 nx ex 10 既上锁又设置过期时间同步进行。
@GetMapping("/testLock") public void testLock(){ //1、获取锁, setnx Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "111", 3, TimeUnit.SECONDS); //2、获取锁成功,查询num的值 if(lock){ Object value = redisTemplate.opsForValue().get("num"); //2.1 判断num为空return if(StringUtils.isEmpty(value)){ return; } //2.2 有值就转成int int num = Integer.parseInt(value + ""); //2。3 把redis的num加1 redisTemplate.opsForValue().set("num", ++num); //2.4 释放锁,del redisTemplate.delete("lock"); }else { //3 获取锁失败,每个0.1秒再获取 try{ Thread.sleep(100); testLock(); }catch(InterruptedException e){ e.printStackTrace(); } } }
存在问题:误删,锁释放错了
a:先操作
1、上锁
2、具体操作
服务器卡顿
3、锁自动释放
b:抢到锁,具体操作
a服务器反应过来,进行操作,手动释放锁,释放了b的锁
方法:使用UUID表示不同操作
1、set lock uuid nx ex 10
2、释放锁时,首先判断当前uuid和要释放锁的uuid是否一样。
@GetMapping("/testLock") public void testLock(){ String uuid = UUID.randomUUID().toString(); //1、获取锁, setnx Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.SECONDS); //2、获取锁成功,查询num的值 if(lock){ Object value = redisTemplate.opsForValue().get("num"); //2.1 判断num为空return if(StringUtils.isEmpty(value)){ return; } //2.2 有值就转成int int num = Integer.parseInt(value + ""); //2。3 把redis的num加1 redisTemplate.opsForValue().set("num", ++num); //2.4 释放锁,del、判断比较uuid是否一样 if(redisTemplate.opsForValue().get("lock").equals(uuid)){ redisTemplate.delete("lock"); } }else { //3 获取锁失败,每个0.1秒再获取 try{ Thread.sleep(100); testLock(); }catch(InterruptedException e){ e.printStackTrace(); } } }
分类:
Redis详细
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构