先說結(jié)論:SET {key} {value} NX EX {seconds}
set命令參考:http://doc.redisfans.com/string/set.html
SETNX
redis支持SETNX命令:http://doc.redisfans.com/string/setnx.html
但是使用SETNX有一個(gè)問題慨蓝,那就是鎖不能永久存在符糊,需要釋放
先看下面的代碼
if (!SETNX)
return
// 業(yè)務(wù)邏輯
DEL
如果在執(zhí)行業(yè)務(wù)邏輯的時(shí)候出現(xiàn)異常,那么就不會(huì)釋放鎖,造成鎖永遠(yuǎn)存在
那么是不是可以把刪除鎖的操作放到finally里梅誓?
try{
if (!SETNX)
return
// 業(yè)務(wù)邏輯
}finally{
DEL
}
但是在執(zhí)行DEL的時(shí)候珊膜,有可能因?yàn)橐恍┨厥獾脑虿荒軋?zhí)行成功瓶佳,比如網(wǎng)絡(luò)抖動(dòng)逢艘,那么鎖依舊得不到釋放
所以需要在SETNX的時(shí)候,就給這個(gè)key設(shè)置一個(gè)大約的過期時(shí)間(比如3秒)祭钉,這樣即使最終沒有DEL瞄沙,也可以防止鎖永遠(yuǎn)不釋放
try{
if (!SETNX)
return
EXPIRE 3s
// 業(yè)務(wù)邏輯
}finally{
DEL
}
同樣的,這樣給key設(shè)置過期時(shí)間慌核,依舊可能因?yàn)橐恍┨厥獾脑虿荒軋?zhí)行成功距境,比如網(wǎng)絡(luò)抖動(dòng),EXPIRE失敗垮卓,然后DEL垫桂,又失敗,鎖得不到釋放
那么SETNX和EXPIRE是否可以放到一個(gè)pipeline或者一個(gè)MULTI中呢粟按?好吧诬滩,我選擇狗帶,幸虧redis提供了一個(gè)單條命令就可以實(shí)現(xiàn)加鎖和設(shè)置過期時(shí)間灭将,那就是set命令疼鸟,用法如我開頭所說