php redis加锁解锁
<?php namespace App\Shop\SecKill; /** * Class RedisLockService redis 锁服务 * @author code.cent123.com */ class RedisLockService { /** * redis锁key */ const REDIS_LOCK_KEY_TEMPLATE = 'LOCKING_KEY_'; /** * redis锁默认超时时间(秒) */ const REDIS_LOCK_DEFAULT_EXPIRE_TIME = 3600; /** * 加redis锁 * @param string $strLockKey * @param int $intExpireTime 锁过期时间(秒) * @return bool|string 加锁成功返回唯一锁ID,加锁失败返回false */ public static function addLock(string $strLockKey, int $intExpireTime = self::REDIS_LOCK_DEFAULT_EXPIRE_TIME) { if (empty($strLockKey) || $intExpireTime <= 0) { return false; } //获取Redis连接 $objRedisConn = redis(); //生成唯一锁ID,解锁需持有此ID $uniqueLockId = self::generateUniqueLockId(); $redisKey = self::REDIS_LOCK_KEY_TEMPLATE . $strLockKey; $bolRes = $objRedisConn->set($redisKey, $uniqueLockId, ['nx', 'ex' => $intExpireTime]); return $bolRes ? (string)$uniqueLockId : false; } /** * 解redis锁 * @param string $strLockKey * @param string $uniqueLockId * @return bool */ public static function unLock(string $strLockKey, string $uniqueLockId): bool { if (empty($strLockKey) || empty($uniqueLockId)) { return false; } $objRedisConn = redis(); $redisKey = self::REDIS_LOCK_KEY_TEMPLATE . $strLockKey;; //监听Redis key防止在比对lock_id与解锁事务执行过程中被修改或删除,提交事务后会自动取消监控,其他情况需手动解除监控 $objRedisConn->watch($redisKey); if ($uniqueLockId == $objRedisConn->get($redisKey)) { $objRedisConn->multi()->del($redisKey)->exec(); return true; } $objRedisConn->unwatch(); return false; } /** * 生成锁唯一ID * @return string */ public static function generateUniqueLockId(): string { return date('Ymd_His') . uniqid('_uniqid_'); //return redis()->incr('LOCK_UNIQUE_ID'); } }
使用示例:
//获取锁 $lock_id = RedisLockService::addLock($redis_key, 10); if (empty($lock_id)) { $res = [ 'status' => 0, 'msg' => '锁定中...', 'date' => date('Y-m-d H:i:s'), ]; return $res; } //业务逻辑 do something ... //删除锁 RedisLockService::unLock($redis_key, $lock_id);