網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Redis setNX分布式鎖超時(shí)時(shí)間失效 -1
使用SETNX加鎖
加鎖的思路:
如果 key 不存在,將 key 設(shè)置為 value,如果 key 已存在,則 SETNX 不做任何動(dòng)作。
使用 RedisTemplate 操作Redis
? ? @Autowired
? ? private RedisTemplate redisTemplate;
?
? ? @RequestMapping("/setNx")
? ? public String setNx() {
? ? ? ? String key = "redis_nx_test";
? ? ? ? String value = "1";
?
? ? ? ? boolean res = redisTemplate.getConnectionFactory().getConnection().setNX(key.getBytes(), value.getBytes());
? ? ? ? log.info("setNX:{}", res);
? ? ? ? if (res) {
? ? ? ? ? ? redisTemplate.getConnectionFactory().getConnection().expire(key.getBytes(), 50);
? ? ? ? ? ? log.info("設(shè)置過(guò)期時(shí)間");
? ? ? ? }
?
? ? ? ? return "success";
? ? }
解決死鎖
考慮一種情況,如果進(jìn)程獲得鎖后,斷開(kāi)了與 Redis 的連接(可能是進(jìn)程掛掉,或者網(wǎng)絡(luò)中斷),如果沒(méi)有有效的釋放鎖的機(jī)制,那么其他進(jìn)程都會(huì)處于一直等待的狀態(tài),即出現(xiàn)“死鎖”。
目前考慮是使用定時(shí)任務(wù)進(jìn)行掃描處理超時(shí)時(shí)間為 -1的key
@Scheduled(initialDelay = 1000,fixedDelay = 1000*60*30)
? ? public void deleteExceptionKey(){
? ? ? ? String key = "redis_nx_test";
? ? ? ??
? ? ? ? //返回 -2 ? 表示這個(gè)key已過(guò)期,已不存在
? ? ? ? //返回 -1 ? 表示這個(gè)key沒(méi)有設(shè)置有效期
? ? ? ? //返回0以上的值 ? 表示是這個(gè)key的剩余有效時(shí)間
? ? ? ? Long l = redisTemplate.opsForValue().getOperations().getExpire(key);
? ? ? ? log.info("Expire:{}", l);
? ? ? ? if(l == -1){
? ? ? ? ? ?Boolean b = ?redisTemplate.delete(key);
? ? ? ? ? ? log.info("刪除key:{},{}", key,b);
? ? ? ? }
? ? }
Redis分布式鎖,超時(shí)問(wèn)題的處理
分布式鎖超時(shí)問(wèn)題解決方案,主要是基于redission。Redisson是架設(shè)在Redis基礎(chǔ)上的一個(gè)Java駐內(nèi)存數(shù)據(jù)網(wǎng)格(In-Memory Data Grid)。充分的利用了Redis鍵值數(shù)據(jù)庫(kù)提供的一系列優(yōu)勢(shì),基于Java實(shí)用工具包中常用接口,為使用者提供了一系列具有分布式特性的常用工具類(lèi)。
redis實(shí)現(xiàn)分布式鎖,主要是通過(guò)SETNX命令,設(shè)置一組 key,value。在同一時(shí)刻只能有一個(gè)線程設(shè)置成功,該線程獲得了分布式鎖。
分布式可能會(huì)出現(xiàn)的超時(shí)問(wèn)題
1、誤刪除別人的鎖
A獲取鎖后,事務(wù)執(zhí)行超時(shí)。鎖到期自動(dòng)釋放,B線程獲取到鎖。A完成事務(wù)后,釋放鎖時(shí),把B的鎖釋放了。
解決方案:
每個(gè)線程在獲取鎖式,在寫(xiě)key-value時(shí),將自己生成的一個(gè)獨(dú)一無(wú)二的id寫(xiě)入value。先校驗(yàn)value,再刪除鎖。這兩個(gè)操作要保證原子性,可以采用Lua腳本。
(如果沒(méi)有保證原子性,會(huì)出現(xiàn)A校驗(yàn)完value,鎖失效。B寫(xiě)入key-value。A刪除B寫(xiě)入的鎖。)
2、A到期自動(dòng)釋放鎖后,B獲得鎖。出現(xiàn)兩個(gè)鎖并行的情況
A獲取鎖后,開(kāi)啟一個(gè)守護(hù)線程,定期為A刷新鎖的時(shí)間。這樣A就是一直保持鎖的情況。在redission源碼中有相應(yīng)的程序。
總結(jié)
原文鏈接:https://blog.csdn.net/woaiwojialanxi/article/details/123346913
相關(guān)推薦
- 2022-02-01 Google Chrome進(jìn)入暗黑模式
- 2022-11-03 tomcat的webapps目錄下的應(yīng)用刪除部署詳解_Tomcat
- 2022-10-23 ASP.NET?Core實(shí)現(xiàn)中間件的幾種方式_實(shí)用技巧
- 2022-10-11 云服務(wù)器搭建redis主從復(fù)制以及哨兵模式(附踩坑記錄)
- 2022-09-22 SGL:Self-supervised Graph Learning for Recommendat
- 2023-11-14 樹(shù)莓派以及l(fā)inux ubuntu 上,各種依賴(lài)不滿(mǎn)足,修復(fù)不了:E: Release file f
- 2022-04-28 WPF簡(jiǎn)介與基礎(chǔ)開(kāi)發(fā)_實(shí)用技巧
- 2023-12-11 Spring利用注解自動(dòng)裝配
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支