網站首頁 編程語言 正文
Redis setNX分布式鎖超時時間失效 -1
使用SETNX加鎖
加鎖的思路:
如果 key 不存在,將 key 設置為 value,如果 key 已存在,則 SETNX 不做任何動作。
使用 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("設置過期時間");
? ? ? ? }
?
? ? ? ? return "success";
? ? }
解決死鎖
考慮一種情況,如果進程獲得鎖后,斷開了與 Redis 的連接(可能是進程掛掉,或者網絡中斷),如果沒有有效的釋放鎖的機制,那么其他進程都會處于一直等待的狀態,即出現“死鎖”。
目前考慮是使用定時任務進行掃描處理超時時間為 -1的key
@Scheduled(initialDelay = 1000,fixedDelay = 1000*60*30)
? ? public void deleteExceptionKey(){
? ? ? ? String key = "redis_nx_test";
? ? ? ??
? ? ? ? //返回 -2 ? 表示這個key已過期,已不存在
? ? ? ? //返回 -1 ? 表示這個key沒有設置有效期
? ? ? ? //返回0以上的值 ? 表示是這個key的剩余有效時間
? ? ? ? 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分布式鎖,超時問題的處理
分布式鎖超時問題解決方案,主要是基于redission。Redisson是架設在Redis基礎上的一個Java駐內存數據網格(In-Memory Data Grid)。充分的利用了Redis鍵值數據庫提供的一系列優勢,基于Java實用工具包中常用接口,為使用者提供了一系列具有分布式特性的常用工具類。
redis實現分布式鎖,主要是通過SETNX命令,設置一組 key,value。在同一時刻只能有一個線程設置成功,該線程獲得了分布式鎖。
分布式可能會出現的超時問題
1、誤刪除別人的鎖
A獲取鎖后,事務執行超時。鎖到期自動釋放,B線程獲取到鎖。A完成事務后,釋放鎖時,把B的鎖釋放了。
解決方案:
每個線程在獲取鎖式,在寫key-value時,將自己生成的一個獨一無二的id寫入value。先校驗value,再刪除鎖。這兩個操作要保證原子性,可以采用Lua腳本。
(如果沒有保證原子性,會出現A校驗完value,鎖失效。B寫入key-value。A刪除B寫入的鎖。)
2、A到期自動釋放鎖后,B獲得鎖。出現兩個鎖并行的情況
A獲取鎖后,開啟一個守護線程,定期為A刷新鎖的時間。這樣A就是一直保持鎖的情況。在redission源碼中有相應的程序。
總結
原文鏈接:https://blog.csdn.net/woaiwojialanxi/article/details/123346913
相關推薦
- 2022-07-22 對稱式加密與非對稱式加密的對比
- 2022-07-29 cypress測試本地web應用_web2.0
- 2022-07-01 Python判斷Nan值的五種方式小結_python
- 2022-12-06 解決R語言報錯:Error?in?y?+?1:non-numeric?argument?to?bin
- 2022-06-29 在Oracle中使用正則表達式_oracle
- 2022-04-22 Element UI 表格操作列按鈕顯示不全
- 2022-11-21 Android自定義ListView實現下拉刷新上拉加載更多_Android
- 2022-05-20 SpringBoot配置文件簡介
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支