redis实现分布式锁
程序员文章站
2022-03-30 19:53:21
...
一、防重情况一:并发情况下只有一个执行,但串行情况(使用线程池)下可以执行多次
RLock rLock = redissonClient.getLock("key-"+msgId); boolean getLock = false; try { if(rLock.tryLock(5,60 * 60 * 24 * 7, TimeUnit.SECONDS)){ getLock = true; this.doBusiness(msgBo,msgId); }else{ log.warn("can not lock:{}",msgId); } } catch (Exception e) { log.error("deal error,msgId={}",msgId,e); //当前业务处理失败,释放锁 if(rLock != null && rLock.isHeldByCurrentThread()){ rLock.unlock(); } throw new RuntimeException(e); } if(!getLock){ throw new RuntimeException("can not get lock"); }
以上发生重复执行的原因,在于虽然设置了加锁时间7天,但如果使用的是线程池,可能后续同一线程消费MQ消息。所以能获取到分布式锁。
二、防重情况二:并发情况下只有一个执行,指定时间范围内不能再执行
String key = "key-"+msgId; boolean getLock = false; try{ if(redisClient.setNx(key,"Y",60*60*24*7)){ getLock = true; this.doBusiness(msgBo,msgId); }else{ log.warn("can not lock:{}",msgId); } }catch (Exception e) { log.error("deal error,msgId={}",msgId,e); //当前业务处理失败,释放锁 if(getLock){ Long delResult = redisClient.del(key); log.info("delResult = {}",delResult); } throw new RuntimeException(e); } if(!getLock){ throw new RuntimeException("can not get lock"); }
上一篇: springmvc+hibernate整合事务不回滚,谁来拯救我
下一篇: 关于国际化问题的探讨