redis會發生死鎖問題嗎
就分散式鎖定而言,一個常用的問題就是如果一個服務setnx成功了,但是在解鎖的時候如果發生了宕機或者一些特殊因素,導致無法解鎖,那麼其他服務將陷入死鎖的狀態。所以,我們在用setnx 的同時想著去用expire 指令對鎖進行一個過期操作, 從指令可以看出setnx 和expire指令是分開的,如果在這中間的空隙過程中如果有特殊因素導致指令無法繼續,也會導致死鎖的產生。
解決方法:
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; @Component public class RedisLock { Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private StringRedisTemplate redisTemplate; /** * 加锁 * @param key * @param value 当前时间 + 超时时间 * @return */ public boolean lock(String key, String value) { if (redisTemplate.opsForValue().setIfAbsent(key, value)) { // 这个其实就是setnx命令,只不过在java这边稍有变化,返回的是boolean // 设置个过期时间,当然如果在这中间的空隙过程中如果有特殊因素导致指令无法继续,也会导致死锁的产生,如果死锁出现,则后续代码会处理 redisTemplate.expire(key, lockTime, TimeUnit.SECONDS); return true; } // 避免死锁,且只让一个线程拿到锁 String currentValue = redisTemplate.opsForValue().get(key); // 如果锁过期了 if (!StringUtils.isEmpty(currentValue) && Long.parseLong(currentValue) < System.currentTimeMillis()) { //获取上一个锁的时间 String oldValues = redisTemplate.opsForValue().getAndSet(key, value); /* 只会让一个线程拿到锁 如果旧的value和currentValue相等,只会有一个线程达成条件,因为第二个线程拿到的oldValue已经和currentValue不一样了 */ if (!StringUtils.isEmpty(oldValues) && oldValues.equals(currentValue)) { return true; } } return false; } /** * 解锁 * @param key * @param value */ public void unlock(String key, String value) { try { String currentValue = redisTemplate.opsForValue().get(key); if (!StringUtils.isEmpty(currentValue) && currentValue.equals(value)) { redisTemplate.opsForValue().getOperations().delete(key); } } catch (Exception e) { logger.error("redis分布式锁解锁异常,{}", e); } } }
呼叫:
//加锁 long time = System.currentTimeMillis() + 1000 * lockTime //超时时间:10秒,最好设为常量 boolean isLock = redisLock.lock(...keyName, String.valueOf(time)); if(!isLock){ throw new RuntimeException("系统正忙"); } // doSomething... //解锁 redisLock.unlock(...keyName, String.valueOf(time));
更多Redis相關知識,請造訪Redis使用教學欄位!
以上是redis會發生死鎖問題嗎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

熱門話題

本文討論了在Redis群集中選擇碎片鍵,並強調了它們對性能,可伸縮性和數據分佈的影響。關鍵問題包括確保均勻數據分配,與訪問模式保持一致以及避免常見錯誤l

本文討論了在REDIS中實施身份驗證和授權,重點是實現身份驗證,使用ACL以及確保REDIS的最佳實踐。它還涵蓋了管理用戶權限和工具以增強重新安全性。

本文討論了使用REDIS進行工作隊列和背景處理,詳細的設置,作業定義和執行。它涵蓋了原子運營和工作優先級等最佳實踐,並解釋了REDIS如何提高處理效率。

本文討論了在REDIS中實施和管理緩存無效的策略,包括基於時間的到期,事件驅動的方法和版本控制。它還涵蓋了緩存到期的最佳實踐和監視和自動的工具

文章討論了使用Redis CLI,Redis Insight和Datadog和Prometheus等工具等工具進行監視REDIS群集的性能和健康。

本文討論了在Web應用程序中使用REDIS進行會話管理,詳細介紹設置,諸如可伸縮性和性能以及安全措施之類的好處。
