DiverseYouthNightSchool/extend/traits/CacheTrait.php

153 lines
3.8 KiB
PHP
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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;
}
}