解決死鎖
如果只用SETNX命令設置鎖的話,如果當持有鎖的進程崩潰或刪除鎖失敗時,其他進程將無法獲取到鎖,問題就大了。
解決方法是在獲取鎖失敗的同時獲取鎖的值,並將值與當前時間進行對比,如果值小於當前時間說明鎖以過期失效,進程可運用Redis的DEL命令刪除該鎖。
setnx的作用和memcache的add方法類似
class rediss { private $redis; function __construct() { $this->redis= $this->redis(); } public function redis(){ $redis = new Redis(); $redis->connect('127.0.0.1','6379') or die('con not redis'); $redis->auth('1234'); return $redis; } public function lock($key,$expire){ $is_lock = $this->redis->setnx($key,(time()+$expire)); //如果setnx賦值成功,則$is_lock返回1,否則返回空 $is_lock=!empty($is_lock) ? 'true' : 'false'; if($is_lock=='true'){ $this->redis->expire($key,$expire); //給鍵值加有效時間 } return $is_lock; } public function delLock($key){ return $this->redis->del($key); } } $bb = new rediss(); $key='hua'; //鍵名 $val=5;//傳的參數 $lock = $bb->lock($key,$val); if($lock=='false'){ $hua = $bb->redis()->get($key); if(time()>$hua){ $bb->delLock($key); echo "刪除"; } }else{ echo $bb->lock($key,$val); //該區域進行sql操作 }
class rediss{private $redis;function __construct(){$this->redis= $this->redis();}public function redis(){$redis = new Redis();$redis->connect('127.0.0.1','6379') or die('con not redis');$redis->auth('1234');return $redis;}public function lock($key,$expire){
$is_lock = $this->redis->setnx($key,(time()+$expire));//如果setnx賦值成功,則$is_lock返回1,否則返回空$is_lock=!empty($is_lock) ? 'true' : 'false';if($is_lock=='true'){$this->redis->expire($key,$expire); //給鍵值加有效時間}return $is_lock;}public function delLock($key){return $this->redis->del($key);}}$bb = new rediss();
$key='hua'; //鍵名$val=5;//傳的參數$lock = $bb->lock($key,$val);if($lock=='false'){$hua = $bb->redis()->get($key);if(time()>$hua){$bb->delLock($key);echo "刪除";}}else{echo $bb->lock($key,$val);//該區域進行sql操作}