mirror of
https://github.com/crmeb/CRMEB.git
synced 2026-10-29 05:50:50 +00:00
62 lines
1.7 KiB
PHP
62 lines
1.7 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
|
||
// +----------------------------------------------------------------------
|
||
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
|
||
// +----------------------------------------------------------------------
|
||
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
|
||
// +----------------------------------------------------------------------
|
||
// | Author: CRMEB Team <admin@crmeb.com>
|
||
// +----------------------------------------------------------------------
|
||
namespace crmeb\utils;
|
||
|
||
use think\facade\Cache;
|
||
|
||
class Lock
|
||
{
|
||
/**
|
||
* @param $key
|
||
* @param $fn
|
||
* @param int $ex
|
||
* @return mixed
|
||
* @author 吴汐
|
||
* @email 442384644@qq.com
|
||
* @date 2023/03/01
|
||
*/
|
||
public function exec($key, $fn, int $ex = 6)
|
||
{
|
||
try {
|
||
$this->lock($key, $key, $ex);
|
||
return $fn();
|
||
} finally {
|
||
$this->unlock($key, $key);
|
||
}
|
||
}
|
||
|
||
public function tryLock($key, $value = '1', $ex = 6)
|
||
{
|
||
return Cache::store('redis')->handler()->set('lock_' . $key, $value, ["NX", "EX" => $ex]);
|
||
}
|
||
|
||
public function lock($key, $value = '1', $ex = 6)
|
||
{
|
||
if ($this->tryLock($key, $value, $ex)) {
|
||
return true;
|
||
}
|
||
usleep(200);
|
||
$this->lock($key, $value, $ex);
|
||
}
|
||
|
||
public function unlock($key, $value = '1')
|
||
{
|
||
$script = <<< EOF
|
||
if (redis.call("get", "lock_" .. KEYS[1]) == ARGV[1]) then
|
||
return redis.call("del", "lock_" .. KEYS[1])
|
||
else
|
||
return 0
|
||
end
|
||
EOF;
|
||
return Cache::store('redis')->handler()->eval($script, [$key, $value], 1) > 0;
|
||
}
|
||
}
|