Laravel全局分布式锁的使用

获取锁的代码: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();