原始redis生成方式
php
<?php
namespace App\Utils;
use Illuminate\Support\Facades\Redis;
use Illuminate\Support\Str;
class RedisLockUtil
{
const EXPIRE_TIME = 10; // 秒
/**
* 加锁
*/
public static function lock(string $key, int $expire = self::EXPIRE_TIME): ?string
{
$token = (string) Str::uuid();
$result = Redis::set(
$key,
$token,
'NX',
'EX',
$expire
);
return $result === 'OK' ? $token : null;
}
/**
* 解锁(必须带 token)
*/
public static function unlock(string $key, string $token): bool
{
$lua = <<<LUA
if redis.call("get", KEYS[1]) == ARGV[1] then
return redis.call("del", KEYS[1])
else
return 0
end
LUA;
return Redis::eval($lua, 1, $key, $token) === 1;
}
}
调用方式
php
$token = RedisLockUtil::lock('order:1', 10);
if (!$token) {
return '系统繁忙';
}
try {
// 业务逻辑
} finally {
RedisLockUtil::unlock('order:1', $token);
}
这里提供一个laravel推荐使用方式
Cache::lock()
为什么 Laravel 官方 Cache::lock() 更安全?
Laravel 已经帮你封装好的
php
$lock = Cache::lock('order:1', 10);
if ($lock->get()) {
try {
//
} finally {
$lock->release();
}
}