深圳网站建设价格是多少钱,电子商务冷门吗,霞浦网站建设,asp制作网站教程一#xff0c;概念
在PHP中实现分布式锁通常可以使用数据库、缓存系统#xff08;如Redis#xff09;或者其他中央存储系统来保证在分布式系统中的数据一致性与同步。秒杀下单、抢红包等等业务场景#xff0c;都需要用到分布式锁。 常规方案大概有七中 方案一#xff1a;…一概念
在PHP中实现分布式锁通常可以使用数据库、缓存系统如Redis或者其他中央存储系统来保证在分布式系统中的数据一致性与同步。秒杀下单、抢红包等等业务场景都需要用到分布式锁。 常规方案大概有七中 方案一SETNX EXPIRE 方案二SETNX value值是系统时间过期时间 方案三使用Lua脚本(包含SETNX EXPIRE两条指令) 方案四SET的扩展命令SET EX PX NX 方案五SET EX PX NX 校验唯一随机值,再释放锁 方案六: 开源框架~Redisson 方案七多机实现的分布式锁Redlock 这里我采用方案三加锁和根据判断解锁都需要保持原子性所以使用Lua脚本
二、代码
?phpclass RedisLock
{private $redis;private $lockKey;public function __construct($lockKey){$this-redis new Redis();$this-redis-connect(127.0.0.1, 6379);$this-lockKey $lockKey;}public function acquireLock(){// 设置锁的超时时间防止死锁在删除锁的时候有可能服务挂了那这个锁就成了死锁设置过期时间可以防止死锁$expire 10;// 生成一个唯一的标识符可能会出现线程A代码未执行完锁已经过期这时候另外一个线程B就能拿到了锁这时线程A执行完毕删除锁如果没有当前线程唯一标识就会删除掉B已经拿到的锁$identifier uniqid();while (!$this-redis-set($this-lockKey, $identifier, [NX, EX $expire])) {// 如果设置失败等待一段时间后重试usleep(1000);}return $identifier;}public function releaseLock($identifier){// 释放锁检查标识符是否匹配确保只有持有锁的请求才能释放锁//这里的判断和删除锁需要保持原子性所以使用Lua脚本来删除if ($this-redis-eval(if redis.call(get,KEYS[1]) ARGV[1] then return redis.call(del,KEYS[1]) else return 0 end, [$this-lockKey, $identifier], 1)) {return true;}return false;}
}// 示例用法
$lock new RedisLock(my_resource);// 尝试获取锁
$identifier $lock-acquireLock();if ($identifier) {// 成功获取锁执行需要同步的操作// 释放锁$lock-releaseLock($identifier);
} else {// 获取锁失败处理冲突或重试逻辑echo Failed to acquire lock\n;
}