JAVA 基於Redis的分佈式鎖

分佈式鎖一般有三種實現方式:

  • 數據庫樂觀鎖

  • 基於ZooKeeper的分佈式鎖

  • 基於Redis的分佈式鎖

這裏主要記錄下基於Redis的分佈式鎖

Redis加鎖

springboot2.1以後的版本可以直接使用redisTemplate提供的setIfAbsent方法進行加鎖 相當於使用redis命令:SET key value [EX seconds] [PX millisecounds] [NX|XX]

redisTemplate.opsForValue().setIfAbsent(key,value,time,TimeUnit)
  • 爲什麼是set命令而不是setNx命令?

因爲setNx 無法設置key過期時間 需要通過expire來爲key設置過期時間,意味着加鎖是兩條命令,不滿足原子性。

  • 鎖的過期時間設置多少合適,是否可以不設置?

鎖的過期時間一定是要有的,不然留着過年麼?過期時間根據具體的業務邏輯來設置,但是一定要大於代碼執行的時間。例如:

//加鎖  鎖的過期時間爲5秒
Boolean lock = redisTemplate.opsForValue().setIfAbsent("111", "11", 5, TimeUnit.SECONDS);
if(lock){
System.out.println("業務邏輯執行在0-8秒範圍內");
}

這個時候肯定是不合適的。

Redis解鎖

  1. 加鎖之後,一定要保證鎖的釋放,所以通常是在finally代碼塊裏面釋放鎖。

  2. 獲取到鎖才釋放鎖,沒有獲取到,不要去釋放鎖,避免釋放其他客戶端加的鎖。

  3. 釋放鎖的時候可以判斷鎖的持有者是否是自己,是自己的才進行釋放。(2和3至少要遵循一個,這樣才能避免誤釋放鎖)

解鎖方式一:

redisTemplate.delete(key)

解鎖方式二:使用lua腳本

if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end

完整的加鎖解鎖代碼如下:

@Autowired
RedisTemplate redisTemplate;

@Test
public void testLock() throws UnknownHostException {
String key = "lockTest";
InetAddress ia = InetAddress.getLocalHost();
String value = ia.toString();
//加鎖 鎖的過期時間爲20秒
Boolean lock = redisTemplate.opsForValue().setIfAbsent(key, value, 20, TimeUnit.SECONDS);
if (!lock) {
//未獲取到鎖,直接返回
return;
}
try {
System.out.println("業務邏輯執行在小於20秒範圍內");
} catch (Exception e) {
System.out.println("業務錯誤信息");
} finally {
// 方式一 直接使用del
redisTemplate.delete(key);
// 方式二 使用lua腳本
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
RedisScript redisScript = new DefaultRedisScript(script);
List<String> keys = new ArrayList<>();
keys.add(key);
redisTemplate.execute(redisScript, keys, value);
}

}

標題:JAVA 基於Redis的分佈式鎖
作者:hjljy
地址:https://www.hjljy.cn/articles/2021/03/05/1614931478736.html

END

版權申明:內容來源網絡,版權歸原創者所有。除非無法確認,我們都會標明作者及出處,如有侵權煩請告知,我們會立即刪除並表示歉意。謝謝。


如果你覺得文章不錯,文末的贊 👍 又回來啦, 記得給我「點贊」和「在看」哦~



本文分享自微信公衆號 - JAVA高級架構(gaojijiagou)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章