這裡只介紹下鎖的實現機制,其餘業務邏輯略過。由於加鎖過程應該是不可拆解的,也就是常說的原子型操作,因此這裡選擇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後,無論成敗,監聽會被移除 悲觀鎖每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖。場景 如果專案中使用了快取且對快取設定了超時時間。當併發...