FastAdmin 锁的使用

1
$ composer require symfony/lock predis/predis

application/common.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
if(!function_exists('lock_acquire')) {
/**
* 获取写锁
* @param \Symfony\Component\Lock\LockInterface $lock 锁实例
* @param float $time 最长时间,单位秒
* @return bool
*/
function lock_acquire(\Symfony\Component\Lock\LockInterface $lock, float $time = 10.0): bool {
$time = (float) bcadd(microtime(true), $time, 4);

while (true) {
// 判断是不是超过获取时间了
if($time >= microtime(true)) {
break;
}

if($lock->acquire()) {
return true;
}

// 暂停一下然后再获取
usleep((100 + random_int(-10, 10)) * 1000);
}

return false;
}
}

application/api/controller/Index.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
use Predis\Client;
use Symfony\Component\Lock\LockFactory;
use Symfony\Component\Lock\Store\RedisStore;

public function index()
{
// 设置存储位置,非 redis 可以看底部参考文档。
$redis = new Client('tcp://127.0.0.1:6379');

$store = new RedisStore($redis);
$factory = new LockFactory($store);

$lock = $factory->createLock('user:1', 300);

// 只获取一次
if($lock->acquire()) {
return '获取到锁';
} else {
return '未获取到锁';
}

// 会一直在获取锁到获取到了或者超时被杀死
$lock->acquire(true);

// 1秒多还获取不到那就返回获取失败
if(lock_acquire($lock, 1)) {
return '获取到锁';
} else {
return '未获取到锁';
}

// ----------------

// 参数分别是,key,释放时间(秒),自动释放(实例被销毁)
$lock = $factory->createLock('user:1', 300, true);

// 创建一个不自动释放的锁
$lock = $factory->createLock('user:1', 300, false);

if(!$lock->acquire()) {
return '未获取到锁';
}

try {
} finally {
// 手动释放
$lock->release();
}

// 获取剩余时间
$lock->getRemainingLifetime();

// 增加释放时间(不应该释放后执行)
// 默认是延长创建时设置的时间,可以第一个参数重新设置一个(秒)
$lock->refresh(100);

// 是不是拥有锁
$lock->isAcquired();

// 是不是已过期
$lock->isExpired();
}

参考

https://symfony.com/doc/current/components/lock.html

往上