Redis分布式鎖原理及實現

2021-08-25 02:24:39 字數 2914 閱讀 1584

ps:該篇博文目錄為【redis分布式鎖使用】中的**有瑕疵,為避免錯誤使用,請移步 ,感興趣的也可以看看到底瑕疵在哪

解決問題:多個程序多台機器,對乙個資料進行的操作的互斥。比如,下訂單和扣庫存的操作,這兩個操作必須連貫,乙個執行緒執行完這兩個操作後,下面乙個執行緒才可以介入執行,如果同時併發執行,極大可能會出現「多賣」的現象。

解決方法

1、sql 層面上:

2、**層面上:

以上三種方法都可以解決問題,今天要討論的是第三種 ------redis分布式鎖

語法:

setnx key value
key設定值為value,如果key不存在,這種情況下等同set命令。 當key存在時,什麼也不做。setnx」set if not exists」的簡寫。

返回值:

例子:

redis> setnx mykey "hello"

(integer) 1

redis> setnx mykey "world"

(integer) 0

redis> get mykey

"hello"

redis>

用途:可以用來枷鎖。比如給商品id加鎖。

詳細命令說明請參考: setnx key value

語法:

getset key value
自動將key對應到value並且返回原來key對應的value。如果key存在但是對應的value不是字串,就返回錯誤。

這個解釋有點拗口,其實可以拆開看,先get,最後再set,返回之前的舊值,如果之前key不存在將返回nil

例子:

redis> incr mycounter

(integer) 1

redis> getset mycounter "0"

"1"redis> get mycounter

"0"redis>

用途:解決死鎖。原理即是將原來的鎖替換成新鎖。

詳細命令說明請參考: getset key value

如下工具類redislock

import lombok.extern.slf4j.slf4j;

import org.springframework.beans.factory.annotation.autowired;

import org.springframework.data.redis.core.stringredistemplate;

import org.springframework.stereotype.component;

import org.springframework.util.stringutils;

/** * redis分布式鎖

*/@component

@slf4j

public class redislock

//假設currentvalue=a 接下來併發進來的兩個執行緒的value都是b 其中乙個執行緒拿到鎖,除非從始至終所有都是在併發(實際上這中情況是不存在的),只要開始時有資料有先後順序,則分布式鎖就不會出現「多賣」的現象

string currentvalue = redistemplate.opsforvalue().get(key);

//如果鎖過期 解決死鎖

if (!stringutils.isempty(currentvalue)

&& long.parselong(currentvalue) < system.currenttimemillis())

}return false;//拿到鎖的就有執行權力,拿不到的只有重新再來,重新再來只得是讓使用者手動繼續搶單

}/**

* 解鎖

* @param key

* @param value

*/public void unlock(string key, string value)

}catch (exception e) ", e);}}

}

由原始碼可以看見,setifabsent來實現加鎖功能,如果一些網路或是io等原因拋異常造成了死鎖,則當當前鎖操作過期時間後,getandset會用新鎖替換掉原來的舊鎖,從而實現解決死鎖問題。

運用:

private static final int timeout = 10 * 1000; //超時時間 10s

@autowired

private redislock redislock;

public void orderproductmockdiffuser(string productid)

/*****如果被鎖,則下面的**都不會被執行*******/

//1.查詢該商品庫存,為0則活動結束。

int stocknum = stock.get(productid);

if(stocknum == 0) else catch (interruptedexception e)

stock.put(productid,stocknum);

}//解鎖

redislock.unlock(productid,string.valueof(time));

}

分布式鎖原理及實現

強烈推薦乙個大神的人工智慧的教程 四 zookeeper實現分布式鎖 五 資料庫實現 多工環境 任務都需要對同一共享資源進行寫操作 對資源的訪問是互斥的 塊加synchronized鎖或者reentrantlock鎖 if setnx key,1 1 finally 存在的問題 命令不是原子操作,可...

redis分布式鎖原理

以redisson為例 rlock lock redissonclient.getlock key lock.lock timeoutsecond,timeunit.seconds 原則 1.自己加的鎖自己釋放,2.鎖到期了業務沒執行完還需續期 if redis.call exists keys 1...

redis分布式鎖原理

舉例子 秒殺方式看醫生,乙個人看5min 1.第一次只允許乙個人直接進行來,x10 00 00進去了,setnx roomid,now 5min 出來時間假如是10 05 00 2.時間到了10 05 00,3個人同時進來,需要去看牆上的鐘錶,乙個人乙個的看 a進入病房看到,看到鐘錶時間10 05 ...