2828< meta property ="og:description " content ="分布式锁 Redission 使用原生Redis设置锁的问题: 服务器拿到锁后宕机,锁不能释放,导致阻塞。 设置锁失效时间可以解决上面的问题,但是会导致新的问题: 设置锁失效时间,在服务器负载过高的时候,会发生锁失效业务还没完成的情况,导致业务代码不互斥。 0信任:不要期待网络服务器按照理想情况运行。 使用Redission自动为锁续命,可以解决上述问题。 String lockKey ">
2929< meta property ="og:locale " content ="zh_CN ">
3030< meta property ="article:published_time " content ="2024-10-26T16:00:00.000Z ">
31- < meta property ="article:modified_time " content ="2025-04-27T13:00:56.340Z ">
31+ < meta property ="article:modified_time " content ="2025-04-28T03:09:45.918Z ">
3232< meta property ="article:author " content ="SIMULEITE ">
3333< meta property ="article:tag " content ="基本操作 ">
3434< meta name ="twitter:card " content ="summary ">
154154 < nav class ="site-state ">
155155 < div class ="site-state-item site-state-posts ">
156156 < a href ="/archives/ ">
157- < span class ="site-state-item-count "> 62 </ span >
157+ < span class ="site-state-item-count "> 63 </ span >
158158 < span class ="site-state-item-name "> 日志</ span >
159159 </ a >
160160 </ div >
@@ -223,7 +223,7 @@ <h1 class="post-title" itemprop="name headline">
223223 < i class ="far fa-calendar-check "> </ i >
224224 </ span >
225225 < span class ="post-meta-item-text "> 更新于</ span >
226- < time title ="修改时间:2025-04-27 21:00:56 " itemprop ="dateModified " datetime ="2025-04-27T21:00:56 +08:00 "> 2025-04-27 </ time >
226+ < time title ="修改时间:2025-04-28 11:09:45 " itemprop ="dateModified " datetime ="2025-04-28T11:09:45 +08:00 "> 2025-04-28 </ time >
227227 </ span >
228228
229229
@@ -247,7 +247,7 @@ <h2 id="redission"><a class="markdownIt-Anchor" href="#redission"></a> Redission
247247< p > 0信任:不要期待网络服务器按照理想情况运行。</ p >
248248</ blockquote >
249249< p > 使用Redission自动为锁续命,可以解决上述问题。</ p >
250- < figure class ="highlight java "> < table > < tr > < td class ="code "> < pre > < span class ="line "> < span class ="type "> String</ span > < span class ="variable "> lockKey</ span > < span class ="operator "> =</ span > req.getTrainDate() + < span class ="string "> "-"</ span > + req.getTrainCode();</ span > < br > < span class ="line "> < span class ="type "> RLock</ span > < span class ="variable "> lock</ span > < span class ="operator "> =</ span > < span class ="literal "> null</ span > ;</ span > < br > < span class ="line "> < span class ="keyword "> try</ span > {</ span > < br > < span class ="line "> lock = redissonClient.getLock(lockKey);</ span > < br > < span class ="line "> < span class ="type "> boolean</ span > < span class ="variable "> tryLock</ span > < span class ="operator "> =</ span > lock.tryLock(< span class ="number "> 0</ span > , TimeUnit.SECONDS);</ span > < br > < span class ="line "> < span class ="keyword "> if</ span > (!tryLock) {</ span > < br > < span class ="line "> LOG.info(< span class ="string "> "获取锁失败"</ span > );</ span > < br > < span class ="line "> < span class ="keyword "> throw</ span > < span class ="keyword "> new</ span > < span class ="title class_ "> BusinessException</ span > (BusinessExceptionEnum.CONFIRM_ORDER_TICKET_COUNT_ERROR);</ span > < br > < span class ="line "> }</ span > < br > < span class ="line "> </ span > < br > < span class ="line "> < span class ="comment "> // Business Code</ span > </ span > < br > < span class ="line "> </ span > < br > < span class ="line "> } < span class ="keyword "> catch</ span > (InterruptedException e) {</ span > < br > < span class ="line "> < span class ="keyword "> throw</ span > < span class ="keyword "> new</ span > < span class ="title class_ "> RuntimeException</ span > (e);</ span > < br > < span class ="line "> } < span class ="keyword "> finally</ span > {</ span > < br > < span class ="line "> LOG.info(< span class ="string "> "释放锁"</ span > );</ span > < br > < span class ="line "> < span class ="keyword "> if</ span > (lock != < span class ="literal "> null</ span > && lock.isHeldByCurrentThread()) {</ span > < br > < span class ="line "> lock.unlock();</ span > < br > < span class ="line "> }</ span > < br > < span class ="line "> }</ span > < br > </ pre > </ td > </ tr > </ table > </ figure >
250+ < figure class ="highlight java "> < table > < tr > < td class ="code "> < pre > < span class ="line "> < span class ="type "> String</ span > < span class ="variable "> lockKey</ span > < span class ="operator "> =</ span > req.getBusinessUniqueKey() + < span class ="string "> "-"</ span > + req.getBusinessCode();</ span > < br > < span class ="line "> < span class ="type "> RLock</ span > < span class ="variable "> lock</ span > < span class ="operator "> =</ span > < span class ="literal "> null</ span > ;</ span > < br > < span class ="line "> < span class ="keyword "> try</ span > {</ span > < br > < span class ="line "> lock = redissonClient.getLock(lockKey);</ span > < br > < span class ="line "> < span class ="type "> boolean</ span > < span class ="variable "> tryLock</ span > < span class ="operator "> =</ span > lock.tryLock(< span class ="number "> 0</ span > , TimeUnit.SECONDS);</ span > < br > < span class ="line "> < span class ="keyword "> if</ span > (!tryLock) {</ span > < br > < span class ="line "> LOG.info(< span class ="string "> "获取锁失败"</ span > );</ span > < br > < span class ="line "> < span class ="keyword "> throw</ span > < span class ="keyword "> new</ span > < span class ="title class_ "> BusinessException</ span > (BusinessExceptionEnum.CONFIRM_ORDER_TICKET_COUNT_ERROR);</ span > < br > < span class ="line "> }</ span > < br > < span class ="line "> </ span > < br > < span class ="line "> < span class ="comment "> // Business Code</ span > </ span > < br > < span class ="line "> </ span > < br > < span class ="line "> } < span class ="keyword "> catch</ span > (InterruptedException e) {</ span > < br > < span class ="line "> < span class ="keyword "> throw</ span > < span class ="keyword "> new</ span > < span class ="title class_ "> RuntimeException</ span > (e);</ span > < br > < span class ="line "> } < span class ="keyword "> finally</ span > {</ span > < br > < span class ="line "> LOG.info(< span class ="string "> "释放锁"</ span > );</ span > < br > < span class ="line "> < span class ="keyword "> if</ span > (lock != < span class ="literal "> null</ span > && lock.isHeldByCurrentThread()) {</ span > < br > < span class ="line "> lock.unlock();</ span > < br > < span class ="line "> }</ span > < br > < span class ="line "> }</ span > < br > </ pre > </ td > </ tr > </ table > </ figure >
251251< blockquote >
252252< p > 锁设计原则:谁持有锁,谁才有资格释放锁。</ p >
253253</ blockquote >
@@ -409,7 +409,7 @@ <h3 id="解决方案-4"><a class="markdownIt-Anchor" href="#解决方案-4"></a>
409409< ol >
410410< li > 牺牲一致性,容忍短时间不一致< sup class ="footnote-ref "> < a href ="#fn1 " id ="fnref1 "> [1]</ a > </ sup >
411411< ul >
412- < li > 延迟双删 :隔一段时间再删除一次缓存</ li >
412+ < li > 延迟删除 :隔一段时间再删除一次缓存,可以丢到消息队列里异步删除 </ li >
413413</ ul >
414414</ li >
415415< li > 牺牲性能,读写锁串行执行,保证并发读写/写写原子执行
0 commit comments