public void redisLock(){
// 1. 佔分布式鎖,去redis佔坑, 要求產生的是唯一標識
String uuid = UUID.randomUUID().toString();
// 2. redis 添加值並且設置過期時間的原子性操作,防止添加值到設置過期時間之間發生問題,導致錯誤產生。
Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 300, TimeUnit.SECONDS);
if (lock){
System.out.println("獲取分佈式鎖成功");
// 加鎖成功 執行業務
executeOther();
// 利用lua腳本 實現原子性刪除操作. 防止在往 redis 發送刪除指令後的響應過程中,redis 存儲的 lock 標識已經改變,響應完成後刪除的是其他服務加上的鎖。
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
// 執行 lua 腳本。獲取 redis 中 key 爲 lock 的值, 判斷值是否等於當前鎖的唯一標識 uuid, 如果是則執行刪除該 key 的回調,否則返回操作失敗碼 0
redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList("lock"), uuid);
}else{
System.out.println("加鎖失敗,等待重試");
// 加鎖失敗 自旋
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return redisLock();
}
}
基於 redis 的分佈式鎖
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.