153 lines
3.8 KiB
PHP
153 lines
3.8 KiB
PHP
<?php
|
||
|
||
namespace traits;
|
||
|
||
use bw\Redis;
|
||
|
||
|
||
/**
|
||
* 缓存
|
||
*/
|
||
trait CacheTrait
|
||
{
|
||
|
||
|
||
private $cache_lock_error_msg = "获取锁失败!";
|
||
|
||
private $cache_lock_thorws_excption = true;
|
||
|
||
public function setCacheLockThorwsExcption($cache_lock_thorws_excption){
|
||
$this->cache_lock_thorws_excption = $cache_lock_thorws_excption;
|
||
return $this;
|
||
}
|
||
|
||
|
||
public function getCacheLockThorwsExcption(){
|
||
return $this->cache_lock_thorws_excption;
|
||
}
|
||
|
||
|
||
|
||
|
||
public function hasRedis($is_interrupt = false) {
|
||
$error_msg = '';
|
||
try {
|
||
$redis = $this->getRedis();
|
||
|
||
// 检测连接是否正常
|
||
$redis->ping();
|
||
} catch (\BadFunctionCallException $e) {
|
||
// 缺少扩展
|
||
$error_msg = $e->getMessage() ? $e->getMessage() : "缺少 redis 扩展";
|
||
} catch (\RedisException $e) {
|
||
// 连接拒绝
|
||
\think\Log::write('redis connection redisException fail: ' . $e->getMessage());
|
||
$error_msg = $e->getMessage() ? $e->getMessage() : "redis 连接失败";
|
||
} catch (\Exception $e) {
|
||
// 异常
|
||
\think\Log::write('redis connection fail: ' . $e->getMessage());
|
||
$error_msg = $e->getMessage() ? $e->getMessage() : "redis 连接异常";
|
||
}
|
||
|
||
if ($error_msg) {
|
||
if ($is_interrupt || $this->cache_lock_thorws_excption) {
|
||
throw new \Exception($error_msg);
|
||
} else {
|
||
$this->setCacheLockErrorMsg($error_msg);
|
||
return false;
|
||
}
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
|
||
public function getRedis() {
|
||
if (!isset($GLOBALS['SPREDIS'])) {
|
||
$GLOBALS['SPREDIS'] = (new Redis())->getRedis();
|
||
}
|
||
|
||
return $GLOBALS['SPREDIS'];
|
||
}
|
||
|
||
|
||
|
||
public function getLock($key,$suffix = "-lock-suffix", $timeout = 120){
|
||
$this->hasRedis(true);
|
||
$redis = $this->getRedis();
|
||
$hashKey = $key.$suffix;
|
||
// $redis->del($hashKey);
|
||
// var_dump($hashKey);die;
|
||
//判断锁是否存在,如果存在,返回错误
|
||
// if ($redis->exists($hashKey)){
|
||
//// var_dump(111111222);die;
|
||
// if($this->cache_lock_thorws_excption){
|
||
// throw new \Exception($this->cache_lock_error_msg);
|
||
// }else{
|
||
// return false;
|
||
// }
|
||
//
|
||
// }
|
||
//如果不存在创建锁并返回
|
||
// $redis->set($hashKey, 1,$timeout);//注释掉
|
||
//替换成原子操作的命令
|
||
$nxLock = $redis->set($hashKey, 1,['nx', 'ex' => $timeout]);
|
||
if ($nxLock == 1) {
|
||
return true;
|
||
} else {
|
||
if($this->cache_lock_thorws_excption){
|
||
throw new \Exception($this->cache_lock_error_msg);
|
||
}else{
|
||
return false;
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
|
||
public function setCacheLockErrorMsg($cache_lock_error_msg){
|
||
$this->cache_lock_error_msg = $cache_lock_error_msg;
|
||
return $this;
|
||
}
|
||
|
||
|
||
public function getCacheLockErrorMsg(){
|
||
return $this->cache_lock_error_msg;
|
||
}
|
||
|
||
|
||
public function freeLock($key,$suffix = "-lock-suffix"){
|
||
$this->hasRedis(true);
|
||
$redis = $this->getRedis();
|
||
if(!$key || !$suffix) return true;
|
||
$hashKey = $key.$suffix;
|
||
|
||
//执行lua脚本,确保删除锁是原子操作
|
||
$lua = 'if redis.call("get",KEYS[1]) == ARGV[1]
|
||
then
|
||
return redis.call("del",KEYS[1])
|
||
else
|
||
return 0
|
||
end';
|
||
$result = $redis->eval($lua, [$hashKey, 1], 1);
|
||
|
||
if ('1' == $result) {
|
||
|
||
return true;
|
||
}
|
||
return false;
|
||
|
||
// if (!$redis->EXISTS($hashKey)) return true;
|
||
// $redis->del($hashKey);
|
||
// return true;
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
}
|