connect('127.0.0.1', 6379);
$this->redis = $redis;
}/**
* @param string $name 参数名
* @param int $exp 过期时间
* @param int $retry 重复次数
* @param int $sleep等待时间
*/
public function lock($name = 'lock',$exp = 30, $retry = 10 , $sleep = 1){
$result = false;
while ($retry-- >= 0){
$value= https://www.it610.com/article/md5(date("Y-m-d H:i:s"));
$result = $this->redis->set( $name , $value , ['NX' , 'EX'=>$exp] );
if ($result) {
$this->lockid[$name] = $value;
echo $name.' 成功获取到锁,正在执行' . "\n";
break;
}
echo $name.'加锁失败·· 正常尝试获取锁' ."\n";
sleep($sleep);
}
return $result;
}/**
* @param $name
* @return mixed
* 删除锁
*/
public function unlock($name){
echo $name.' 正常执行解锁···' ."\n";
$lua = "
local key= KEYS[1]
local value = https://www.it610.com/article/ARGV[1]if(redis.call('get', key) == value)
then
return redis.call('del', key)
end";
return $this->redis->eval($lua, [$name, $this->lockid[$name]], 1);
}}// 申请分布式锁
$obj = new locks();
// 执行完成申请解锁
if($obj->lock($name = "lock_1")){
echo "执行结束,等待5s执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){
echo $name.' 解锁成功··' ."\n";
}
}
【PHP+Redis+Lua 实现Redis分布式锁】Redis申请分布式锁的命令,此命令符合原子性:
/**
* SET:Redis的String指令
* lock_name:锁的名称
* unique_id:锁的唯一校验
* NX:时间单位
* PX:设置过期时间
*/SET lock_name unique_id NX PX expire_time
分别执行,具体执行结果:
lock($name = "lock_1")){
echo "执行结束,等待5s执行解锁操作···"."\n";
sleep(5);
echo "--------------------------"."\n";
$unlockResult = $obj->unlock($name);
if($unlockResult){
echo $name.' 解锁成功··' ."\n";
}
}
客户端1:
文章图片
客户端2:
文章图片