【www.bbyears.com--redis】
使用Redis加锁的方式可以防止重复操作,包括表单提交,ajax等http请求,它的原理就是redis的incr命令给键自增,如果返回值不是1,就表示是重复请求,具体看代码:
代码如下/**
* 锁定请求
* @param int $expire 锁定时间
* @param string $mark 自定义标记
* @return bool
*/
protected function lock($expire=1,$mark=""){
$url=strtolower(MODULE_NAME."/".ACTION_NAME);//操作地址
$prefix="lock_";$sid=$_COOKIE[C("SESSION_OPTIONS.name")];
$key=$prefix.md5($sid.$url.$mark);//令牌键值
/**
* @var Redis $redis
*/
$redis = D("Redis");
if($redis->incr($key)==1){
return $redis->expire($key,$expire);
}
return false;
}
这里也要讲讲Redis的incr命令的用法:
INCR key命令用法
将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
代码如下redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21
redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"
返回值是incr之后的值。
如果incr一个不存在的键,它会自动创建这个键并返回值1.
expire 命令示例:
expire key 22
设置键名为key(必须存在)的过期时间为22s.
再回到开始处定义的lock方法,键值为lock+当前操作地址+cookie值+自定义字符串,进行incr操作并使用expire命令设置过期时间默认1s,如是是第一次请求会返回1(expire设置缓存成功),表示设置缓存时间成功,否则返回false表示重复请求或操作。
使用的时候:
代码如下 if(!$this->lock(1)){
//重复操作了
}
这样就可以判断是重复操作了。
代码如下
$this->unlock()
这样就解锁了,可以允许第二次一样的提交。
看看解锁方法:
代码如下
/**
* 解锁请求
* @param string $mark 自定义标记
* @return bool
*/
protected function unlock($mark=""){
$url=strtolower(MODULE_NAME."/".ACTION_NAME);//操作地址
$prefix="lock_";$sid=$sid=$_COOKIE[C("SESSION_OPTIONS.name")];
$key=$prefix.md5($sid.$url.$mark);//令牌键值
/**
* @var Redis $redis
*/
$redis = D("Redis");
return $redis->del($key);
}
这里使用了Redis的del命令。