获取锁的代码:vendor/laravel/framework/src/Illuminate/Cache/RedisLock.php
/** * Attempt to acquire the lock. * * @return bool */ public function acquire() { if ($this->seconds > 0) { return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true; } else { return $this->redis->setnx($this->name, $this->owner) === 1; } }
Redis的set有些特殊:vendor/laravel/framework/src/Illuminate/Redis/Connections/PhpRedisConnection.php
/** * Set the string value in argument as value of the key. * * @param string $key * @param mixed $value * @param string|null $expireResolution * @param int|null $expireTTL * @param string|null $flag * @return bool */ public function set($key, $value, $expireResolution = null, $expireTTL = null, $flag = null) { return $this->command('set', [ $key, $value, $expireResolution ? [$flag, $expireResolution => $expireTTL] : null, ]); }
如果在获取锁的时候传了时间,调用redis的set的时候,调用的其实是:
$redis->set($key, $value, [‘NX’, ‘EX’ => $expireTTL])
也就是说不存在的时候才设置该key,过期时间为秒。
Redis的Set操作的参数参考:
- EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
- PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
- NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
- XX :只在键已经存在时,才对键进行设置操作。
锁的常规使用:
// 设置foo锁的超时时间为5,超过这个时间自动释放 $lock = Cache::lock("foo", 5); if (!$lock->get()) { return false; } // 业务处理 $lock->release(); return true;
在指定的时间内获取到锁,如果获取不到会抛出异常:
// 设置foo锁的超时时间为5,超过这个时间自动释放 $lock = Cache::lock("foo", 5); // 需要在2秒内获取到锁,否则会抛出异常 $lock->block(2); // 业务处理 $lock->release();