解决死锁
如果只用SETNX命令设置锁的话,如果当持有锁的进程崩溃或删除锁失败时,其他进程将无法获取到锁,问题就大了。
解决方法是在获取锁失败的同时获取锁的值,并将值与当前时间进行对比,如果值小于当前时间说明锁以过期失效,进程可运用Redis的DEL命令删除该锁。
setnx的作用和memcache的add方法类似
class RedLock{
//连接redis
static public function redis (){
$redis=new Redis();
$redis->connect('127.0.0.1','6379') or die('Con not content redis');
if($redis){
return $redis;
}else{
die('con not content redis');
}
}
//加锁
public function lock($key,$expire=5){
$redis=self::redis();
$is_lock=$redis->setnx($key,time()+$expire);
if(!$is_lock){
$lock_time=$redis->get($key);
//锁已过期,重置
if($lock_time<time()){
$this->unlock($key);
$is_lock=$redis->setnx($key,time()+$expire);
}
}
return $is_lock ? true : false;
}
// 释放锁
public function unlock($key){
$redis=self::redis();
return $redis->del($key);
}
}
$hua = new RedLock();
$lock=$hua->lock('lock');
$str='';
if($lock){
//逻辑代码
$hua->unlock('lock');
file_put_contents('lock.log',var_export('true',true),FILE_APPEND);
}else{
sleep(1);
file_put_contents('lock.log',var_export('false',true),FILE_APPEND);
}