chrisharrison / lock
通过首先获取锁来避免PHP代码的并发执行。
4.0.0
2020-01-13 11:12 UTC
Requires
- php: ^7.2
- chrisharrison/clock: ^1.0
Requires (Dev)
- phpunit/phpunit: ^8.2
- squizlabs/php_codesniffer: ^3.4
This package is auto-updated.
Last update: 2024-09-13 21:10:38 UTC
README
通过首先获取锁来避免PHP代码的并发执行。
安装
显然是通过Composer
composer require chrisharrison/lock
为什么?
如果你的代码在两个并行处理同时运行时可能会导致不希望出现的竞争条件,你可能想要引入一个锁,以确保只有当一个进程执行该代码时,其他进程才等待。
用法
首先创建一个 LockGuard
$lockGuard = new LockGuard(
$maxAttempts,
$attemptIntervalSeconds,
$lockDriver,
$lockInspector
);
$maxAttempts
:int
在放弃前尝试获取锁的最大次数。$attemptIntervalSeconds
:int
尝试获取锁之间的秒数。$lockDriver
:LockDriver
处理将锁持久化到任何存储机制的类的实例。$lockInspector
:LockInspector
处理测试锁有效性的类的实例。
一旦创建了 LockGuard
,就可以用它来保护锁内的代码。
$flag = false;
$uniqueProcessId = '<ANY-UNIQUE-STRING>';
$lockUntil = DateTimeImmutable::createFromFormat('U', time()+300); // In 5 mins time
$didExecute = $lockGuard->protect('uniq-process-id', $lockUnitl, function () use (&$flag) {
$flag = true;
});
上面的代码将尝试将 $flag
设置为 true
。
如果存在一个尚未过期且不是由同一进程(通过 $uniqueProcessId
识别)创建的锁,则代码将执行,方法将返回 true
。否则返回 false
。一旦代码成功执行,锁将被释放。即使没有达到 $lockUntil
时间,也会发生这种情况。然而,如果在达到 $lockUntil
时间后代码仍未完成,则锁将过期,其他进程可以再次执行。这是为了减轻锁永远不会释放的情况。
典型用法
$lockPath = 'lock.json';
$maxAttempts = 5;
$attemptIntervalSeconds = 3;
$lockDriver = new FilesystemLockDriver($lockPath);
$lockInspector = new DefaultLockInspector;
$lockGuard = new LockGuard(
$maxAttempts,
$attemptIntervalSeconds,
$lockDriver,
$lockInspector
);
FilesystemLockDriver
将锁作为JSON持久化到本地文件系统中的文件。你可以创建其他使用其他方法的 LockDriver
,例如使用 FlySystem 利用S3。