解决方式:利用redis进行加锁,同一时间内,只能先执行一个脚本
<?php
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$lockKey = 'my_lock_key';
$timeout = 10; // 锁超时时间
// 加锁
function acquireLock($redis, $lockKey, $timeout) {
$identifier = uniqid(); // 生成唯一标识符
$end = time() + $timeout;
while (time() < $end) {
if ($redis->set($lockKey, $identifier, ['NX', 'EX' => $timeout])) {
return $identifier;
} else if ($redis->ttl($lockKey) == -1) {
// 防止锁没有正常释放而导致的死锁情况
$redis->expire($lockKey, $timeout);
}
usleep(100000); // 等待100毫秒
}
return false;
}
// 释放锁
function releaseLock($redis, $lockKey, $identifier) {
$script = "
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
";
$redis->eval($script, [$lockKey, $identifier], 1);
}
// 使用示例
$identifier = acquireLock($redis, $lockKey, $timeout);
if ($identifier) {
try {
// 在这里执行需要加锁的操作
echo "成功获取锁,进行任务处理\n";
sleep(5);
} finally {
releaseLock($redis, $lockKey, $identifier);
echo "释放锁\n";
}
} else {
echo "未能获取锁,任务正在执行中\n";
}