redis = RedisService::getRedisInstance(); $this->lockKey = $lockKey; $this->lockValue = uniqid(); // 生成一个唯一的值作为锁的值 $this->lockTimeout = $lockTimeout; } /** * @throws BusinessException */ public function acquireLock($callback) { $result = $this->redis->set($this->lockKey, $this->lockValue, 'ex', $this->lockTimeout, 'nx'); if (empty($result) || $result->getPayload() !== 'OK') { throw new BusinessException("处理中,请稍后再试"); } try { return $callback(); }catch (\Throwable $throwable){ throw new BusinessException($throwable->getMessage(), $throwable->getCode()); } finally { $this->releaseLock(); } } private function releaseLock() { // 释放锁,只有锁的值匹配时才会删除锁,以避免误释放 $script = " if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end "; $this->redis->eval($script, 1, $this->lockKey, $this->lockValue); } public function renewLock() { // 续期锁的过期时间 $this->redis->expire($this->lockKey, $this->lockTimeout); } }