cheprasov/php-redis-lock

RedisLock for PHP 是一个用于在多线程执行环境中限制资源访问的同步机制。锁的设计是为了强制执行互斥的并发控制策略。

资助包维护!
cheprasov

安装: 335,933

依赖者: 1

建议者: 0

安全: 0

星标: 101

关注者: 3

分支: 27

开放问题: 0

1.0.3 2017-10-08 15:56 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:42:09 UTC


README

MIT license Latest Stable Version Total Downloads

RedisLock v1.0.3 for PHP >= 5.5

关于

RedisLock for PHP 是一个用于在多线程执行环境中限制资源访问的同步机制。锁的设计是为了强制执行互斥的并发控制策略。基于 redis

用法

创建一个新的 RedisLock 实例

<?php
require 'vendor/autoload.php';

use RedisLock\RedisLock;
use RedisClient\ClientFactory;
use RedisClient\RedisClient;

// Create a new Redis instance
$Redis = ClientFactory::create([
    'server' => 'tcp://127.0.0.1:6379'
]);

$Lock = new RedisLock(
    $Redis, // Instance of RedisClient,
    'key', // Key in storage,
);

锁定进程的用法

<?php
require 'vendor/autoload.php';

use RedisLock\RedisLock;
use RedisClient\ClientFactory;
use RedisClient\RedisClient;

// Create a new Redis instance
$Redis = ClientFactory::create([
    'server' => 'tcp://127.0.0.1:6379'
]);

// ...

/**
 * Safe update json in Redis storage
 * @param Redis $Redis
 * @param string $key
 * @param array $array
 * @throws Exception
 */
function updateJsonInRedis(RedisClient $Redis, $key, array $array) {
    // Create new Lock instance
    $Lock = new RedisLock($Redis, 'Lock_'.$key, RedisLock::FLAG_DO_NOT_THROW_EXCEPTIONS);

    // Acquire lock for 2 sec.
    // If lock has acquired in another thread then we will wait 3 second,
    // until another thread release the lock. Otherwise it throws a exception.
    if (!$Lock->acquire(2, 3)) {
        throw new Exception('Can\'t get a Lock');
    }

    // Get value from storage
    $json = $Redis->get($key);
    if (!$json) {
        $jsonArray = [];
    } else {
        $jsonArray = json_decode($json, true);
    }

    // Some operations with json
    $jsonArray = array_merge($jsonArray, $array);

    $json = json_encode($jsonArray);
    // Update key in storage
    $Redis->set($key, $json);

    // Release the lock
    // After $lock->release() another waiting thread (Lock) will be able to update json in storage
    $Lock->release();
}

updateJsonInRedis($Redis, 'json-key', ['for' => 1, 'bar' => 2]);
updateJsonInRedis($Redis, 'json-key', ['for' => 42, 'var' => 2016]);

方法

RedisLock :: __construct ( RedisClient $Redis , string $key [, int $flags = 0 ] )

创建一个新的 RedisLock 实例。

方法参数
  1. RedisClient $Redis - RedisClient 的实例
  2. string $key - Redis 存储中的键名称。只有具有相同名称的锁才会相互竞争。
  3. int $flags, 默认 = 0
    • RedisLock::FLAG_DO_NOT_THROW_EXCEPTIONS - 使用此标志,如果您不想自己捕获异常。如果您想对锁的情况有完全控制,请不要使用此标志。默认情况下,如果没有此标志,将抛出所有异常。
示例
$Lock = new RedisLock($Redis, 'lockName');
// or
$Lock = new RedisLock($Redis, 'lockName', RedisLock::FLAG_DO_NOT_THROW_EXCEPTIONS);

bool RedisLock :: acquire ( int|float $lockTime , [ float $waitTime = 0 [, float $sleep = 0.005 ] ] )

尝试获取锁 $lockTime 秒。如果在另一个线程中已经获取了锁,我们将等待 $waitTime 秒,直到另一个线程释放锁。否则,方法将抛出异常(如果未设置 FLAG_DO_NOT_THROW_EXCEPTIONS)或返回结果。成功时返回 true,失败时返回 false

方法参数
  1. int|float $lockTime - 锁的时间(秒),值必须是 >= 0.01
  2. float $waitTime,默认 = 0 - 等待锁的时间(秒)。如果您不想等待锁释放,请使用 0
  3. float $sleep,默认 = 0.005 - 检查锁可用性的迭代之间的等待时间。
示例
$Lock = new RedisLock($Redis, 'lockName');
$Lock->acquire(3, 4);
// ... do something
$Lock->release();

bool RedisLock :: update ( int|float $lockTime )

如果已经获取了锁,则设置新的锁时间。成功时返回 true,失败时返回 false。方法可以抛出异常。

方法参数
  1. int|float $lockTime - 请参阅 RedisLock :: acquire 方法的描述
示例
$Lock = new RedisLock($Redis, 'lockName');
$Lock->acquire(3, 4);
// ... do something
$Lock->update(3);
// ... do something
$Lock->release();

bool RedisLock :: isAcquired ( )

检查此锁是否已获取。成功时返回 true,失败时返回 false

bool RedisLock :: isLocked ( )

检查此锁是否已获取且未过期,并且仍然活跃。成功时返回 true,失败时返回 false。方法可以抛出异常。

bool RedisLock :: isExists ()

锁是否存在或在哪里已被获取?如果锁存在,则返回 true;如果不存在,则返回 false

安装

Composer

下载Composer

wget -nc https://getcomposer.org.cn/composer.phar

并将依赖添加到您的项目中

php composer.phar require cheprasov/php-redis-lock

运行测试

要在控制台中运行测试,请输入

./vendor/bin/phpunit

有些东西不工作

请随意fork项目,修复bug,最终请求合并