當前位置:
首頁 >
前端技术
> javascript
>内容正文
javascript
SpringBoot实现Redis分布式锁
生活随笔
收集整理的這篇文章主要介紹了
SpringBoot实现Redis分布式锁
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
前言
當不同的進程,必須以獨占資源的方式實現資源共享,就需要用到分布式鎖。
安全和穩定性
分布式鎖的實現,必須滿足以下2個特性
- 獨享互斥:在任意一個時刻,只能有一個客戶端持有鎖
- 無死鎖:既然有加鎖,則必須存在解鎖。即使持有鎖的客戶端崩潰宕機,鎖仍然允許被其他客戶端獲取,不能造成無限期的等待
例子1
@Autowired private StringRedisTemplate stringRedisTemplate;@GetMapping("/lock") public void lock1() throws InterruptedException {String lockKey = "lockKey", lockValue = "lockValue";Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10));if (success){try{System.out.println(String.format("Thread-%d:Success", Thread.currentThread().getId()));}finally {stringRedisTemplate.delete(lockKey);}} }- 獨享互斥:setIfAbsent等同于Redis的SETNX命令,當key不存在才生效,返回的是true;當key存在時返回false。
- 無死鎖:setIfAbsent第3個參數是key超時時間,就算中途應用服務掛了,等時間到了key自動失效。另外,finally處理刪除key操作,及時釋放鎖。
用JMeter發送1000個并發請求,結果如下:
Thread-227:Success Thread-88:Success Thread-116:Success Thread-202:Success Thread-185:Success Thread-97:Success但是,上述Demo存在以下問題:
例子2
public void lock3() throws InterruptedException {String lockKey = "lockKey";//lock value改成唯一性的UUIDString lockValue = UUID.randomUUID().toString();Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10));if (success){try{System.out.println(String.format("Thread-%d:Success", Thread.currentThread().getId()));}finally {//釋放鎖不再是簡單的DELETE KEYreleaseLock(lockKey, lockValue);}} } private boolean releaseLock(String key, String value){String srcValue = stringRedisTemplate.opsForValue().get(key);if (StrUtil.isEmpty(srcValue)){return true;}else if (srcValue.equals(value)){stringRedisTemplate.delete(key);return true;}return false; }上面增加了releaseLock函數:
擴展鎖
如果你的業務邏輯可以拆解成多個小步驟,可以將鎖的有效時間設置短一些。在業務處理的過程中,當發現KEY的有效期很短時,再次延長其有效期(前提還是key存在并且value是之前設置的value)
總結
以上是生活随笔為你收集整理的SpringBoot实现Redis分布式锁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Redis RDB、AOF持久化详解
- 下一篇: 1.Spring Cloud Aliba