1、用户交易锁,防止用户重复点击
2、设置并发锁
/**
* 用户交易锁,防止用户重复点击
* @param boolean $action 为true时手动解锁
* @return [type] [description]
*/
public function trade_lock($action = false)
{
global $_GPC;
global $_W;
$mid = $_W["mid"];
$user_key = $mid;
if(!empty($_POST) && is_array($_POST))
{
$user_key .= '_'.serialize($_POST);
}
$redis = m("redis")->getInstance()->getRedisConn();
$exp_time = 30;
$siteurl = $_W["siteurl"];
$lock_key = "__{$siteurl}_trade_lock_{$user_key}";
if($action === true)
{
$redis->delete($lock_key);
}else{
if($redis->exists($lock_key))
{
show_json(0, '当前请求正在处理,请勿重复操作');
}
// redis请求限制
$redis->setex($lock_key, $exp_time, 1);
}
}
/**
* 设置并发锁
* @param string $lock_key 锁键
* @param boolean $action 为true时删除锁
* @return boolean true: 锁成功,false,锁失败,当前键正在交易之中
*/
public function concurrent_lock($lock_key, $action = false)
{
global $_W;
$redis = m("redis")->getInstance()->getRedisConn();
$lock_key = $_W['setting']['site']['key'].'_'.$lock_key;
if($action === true)
{
$redis->delete($lock_key);
}else{
// 是否获得锁
if($redis->setnx($lock_key, time()+3))
{
return true;
}else{
// 没有获得锁,查看锁是否有效
$exp = $redis->get($lock_key);
// 锁已经失效
if($exp < time())
{
// 更新过期时间并检查过期时间
$cexp = $redis->getset($lock_key, time()+3);
if($exp === $cexp)
{
return true;
}
return false;
}
}
return false;
}
}
原生可用
function rlock($lock_key, $lifetime = 3)
{
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379);
// 是否获得锁
if ($redis->setnx($lock_key, time()+$lifetime)) {
$redis->expire($lock_key, $lifetime);
return true;
}else{
$exp = $redis->get($lock_key);
if($exp < time())
{
$redis->del($lock_key);
return true;
}
}
return false;
}
