Redis 在 PHP 中并发锁的使用说明
Redis 并发锁是利用 Redis 的原子性命令(如 SETNX
、SET
带参数)实现的分布式锁,用于解决 PHP 多进程 / 多服务环境下的资源竞争问题(如库存扣减、订单重复提交),确保同一时间只有一个进程能操作共享资源。
- 原子性:锁的 “获取” 和 “设置过期时间” 需一步完成,避免进程崩溃导致死锁。
- 过期自动释放:为锁设置合理过期时间,防止持锁进程异常时锁无法释放。
- 唯一标识:用随机字符串(如
uniqid()
生成)作为锁的值,确保进程只能释放自己持有的锁。
- 非阻塞(可选):获取锁失败时可直接返回,避免进程阻塞等待。
<?php
namespace common\library\traits\redis;
trait LockTrait
{
protected $lockKey; // 锁key
/**
* 加锁
*
* @param mixed $key
*/
public function lock($key, int $expireIn = 5, int $wait = 0): bool
{
$this->lockKey = $key;
do {
$lock = $this->setNx($key, time(), $expireIn);
if ($lock) {
return true;
}
if ($wait > 0) {
sleep(1);
}
} while ($wait--); // 防止偶尔性的获取锁失败的情况
// 无法正常获取锁 不允许往下进行
return false;
}
/**
* 释放锁
*/
public function unlock(): bool
{
return $this->delete($this->lockKey);
}
}
- 过期时间设置:需根据业务实际执行时间调整(如业务需 3 秒,过期时间设 5 秒),过短可能导致锁提前释放,过长可能增加死锁风险。
- Redis 可用性:若 Redis 单点故障,会导致锁失效,生产环境建议用 Redis 集群(主从 + 哨兵)保证高可用。
- 阻塞需求处理:若需要 “获取锁失败后等待重试”,可在
acquire()
方法中添加循环(如循环 3 次,每次间隔 100ms),避免频繁请求 Redis。
- 业务幂等性:即使使用锁,仍需保证业务接口的幂等性(如订单提交时校验订单号是否已存在),防止极端情况下的重复操作。
发布时间 : 2025-09-04,阅读量:1
本文链接:
https://upwqy.com/details/989.html