用redis實現悲觀鎖(後端語言以php為例)

2021-08-14 15:38:17 字數 1714 閱讀 6963

這裡只介紹下鎖的實現機制,其餘業務邏輯略過。由於加鎖過程應該是不可拆解的,也就是常說的原子型操作,因此這裡選擇redis中的setnx操作作為加鎖的方法。

簡化版的**如下:

這段**有個問題,就是setnx成功,但expire失敗,這就可能存在死任務的情況。解決這個問題的一種通用方法是通過使

function

lock

($strmutex, $inttimeout)

return

false;

}

用incr方法代替setnx,具體如下:

這段**通過$intmaxtimes來保證即使在expire未成功的時候也能強制解鎖,保證系統不會出現死任務

function lock($strmutex, $inttimeout, $intmaxtimes

=0)

if ($intmaxtimes

>0&&

$intret

>=

$intmaxtimes

&&$objredis

->ttl($strmutex) ===

-1)

return

false;

}

還有沒有更好的方法呢?

其實redis中的set操作已相容了setnx,並且支援設定過期時間。

function

lock

($strmutex, $inttimeout)

return

false;

}

這個方法是我認為目前最好的,但是為什麼沒有直接介紹這個方法,而是先介紹incr那個方法呢?其實細心的同學可以看到上面那個方面有兩個加粗的字」通用「。之所以這麼說是因為set方法是從redis2.6.12版本才開始支援多引數的。
用完之後解鎖:

//以上程式走完刪除鎖

//檢測鎖是否過期,過期鎖沒必要刪除

if($redis

->ttl($lockkey))

專案示例
/**

* redis鎖單

* *@param string $strmutex 鎖的key

*@param int $inttimeout 鎖的有效期

*@param int $intmaxtimes 最大加鎖次數,一般不用改

*@return bool

*/public

static

function

lockredis

($strmutex, $inttimeout, $intmaxtimes = 0)

if ($intmaxtimes > 0 && $intret >= $intmaxtimes && $objredis->ttl($strmutex) === -1)

return

false;

}/**

* redis解鎖單

* *@param string $strmutex 鎖的key

*/public

static

function

unlockredis

($strmutex)

}

用redis實現悲觀鎖(後端語言以php為例)

通常使用的鎖分為樂觀鎖,悲觀鎖這兩種,簡單介紹下這兩種鎖,作為本文的背景知識,對這類知識已經有足夠了解的同學可以跳過這部分。其實說白了,就是好比乙個健身房裡只有一台跑步機,在健身房門口有個排號機,每個進健身房的人都得先領乙個號碼才能進入,如果跑步機上有人,則在一邊做做熱身 喝喝水,如果跑步機上沒人,...

Redis 事務(悲觀鎖 樂觀鎖)

1 定義 redis事務是乙個單獨的隔離操作 事務中所有的命令都會被序列化 按照順序執行 事務在執行過程中不會被其他客戶端傳送來的命令請求打斷 2 作用 串聯多個命令防止別的命令插隊 multi 輸入開始命令 exec 執行命令 discard 放棄組隊 刪除掉 3 注意事項 1 multi 命令不...

Redis鎖,悲觀鎖和樂觀鎖

樂觀鎖開啟事務前,設定對資料的監聽 watch exec時,如果發生資料發生過修改,作用於改資料的事務會自動取消 discard 事務exec後,無論成敗,監聽會被移除 悲觀鎖每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖。場景 如果專案中使用了快取且對快取設定了超時時間。當併發...