1.方法
public function locklock(){
$api_begin = time();
// 第一个参数锁的名字,第二个参数自动释放锁的时间,,对用户加锁的话,就是第一个参数后面加变量
lock('locklock',3);
Db::startTrans();
try{
// 执行方法,在这里超过锁的时间直接终止回滚
$api_end=time();
$use_time=round(($api_end-$api_begin),0);
echo '耗时'.$use_time.'<br>';
if($use_time > 3){
exit(json_encode(array('code'=>0,'msg'=>'访问超时!'),JSON_UNESCAPED_UNICODE));
}
// 事务提交
Db::commit();
// 删除锁
unlock('locklock');
} catch (\Exception $e) {
// 回滚事务
Db::rollback();
$this->error($e->getMessage());
}
}
2.封装的lock方法
/**
* 方法锁,使用lua脚本封装的redis方法
*/
function lock($lock,$ttl,$value=1){
$lua = new LuaService();
$lock = $lua->lockByLua($lock,$value,$ttl);
if(!$lock){
exit(json_encode(array('code'=>0,'msg'=>'服务繁忙,排队中!')));
}
}
/**
* 删除锁
*/
function unlock($key){
$redis = new Redis();
$redis->del($key);
return true;
}
3.lua脚本方法
/**
* 加锁操作
* 订单,用户,方法都可用
* lua脚本
*/
public function lockByLua($key,$value,$ttl=5){
$lua = <<<eof
local key = KEYS[1]
local value = ARGV[1]
local ttl = ARGV[2]
if redis.call('setnx', key, value) == 1 then
return redis.call('expire', key, ttl)
else
return 0
end
eof;
$redis = new Redis;
$lock = $redis->eval($lua,array($key,$value,$ttl),1);
if(!$lock){
return false;
}
return true;
}