이 기사에서는 특정 참조 가치가 있는 php redis의 잠금 및 잠금 해제를 주로 소개합니다. 도움이 필요한 친구들이 참고할 수 있습니다.
사업 배경 : 룸 체스와 카드 게임에서는 동시 작업으로 인한 Redis 데이터의 더티 읽기를 방지하기 위해 잠금이 필요합니다. 예를 들어 룸에 입장하는 사용자의 작업을 추가하는 경우:
동시성의 경우 get RoomUsers는 더티 읽기를 갖게 됩니다. ;
솔루션 아이디어: 다른 동시 클라이언트가 기다리는 동안 한 번에 한 명의 클라이언트만 작업할 수 있도록 룸을 잠급니다. 즉, ----- 잠금을 차단합니다. redis 추가 잠금 방법에는 incr, set, setnx, hSetnx가 있습니다. Redis 잠금의 여러 구현
$roomId = $_GET['roomId']; $user = $_GET['user']; // '张三' $key = "LockRoom:{$roomId}"; $value = $roomId.uniqid(); $ex = 3; // 如果 $key 不存在的话,就设置 $key 的值为 $value,且有效期为 3s; // return TRUE / FALSE while(true){ $res = $this->redis->set($key, $value, ['nx', 'ex' => $ex]); if($res) { break; } usleep(5000); } // 将用户添加进房间 $roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五'] $roomUsers[] = $user; $this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']
: 물론 잠금을 해제해야 합니다. 작업 후 잠금을 해제하지 않으면 최소 3초를 기다려야 합니다.
잠금을 해제하려면 삭제를 사용하여 키를 삭제하세요. 하지만 여기에는 함정이 있습니다. client01이 키를 획득했다고 가정하면 삭제를 직접 사용할 수 없습니다. 잠금, 방에 입장할 사용자를 추가하는 과정에서 시간이 3초를 초과합니다. 이 때 client02도 잠금을 획득하고 3S를 설정한 다음, client01이 작업을 완료하고 키를 삭제하면 client02가 설정한 잠금이 설정됩니다.// 将用户添加进房间 $roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五'] $roomUsers[] = $user; $this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三'] // lua 脚本解锁 // 先判断 key的值是否为 value, TRUE 才会删除, 所以 $value 的设计要有随机唯一性 $script = 'if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end '; $this->redis->eval($script, array($key , $value), 1);
위 코드는 참조용일 뿐입니다! !
위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되었으면 좋겠습니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요!
관련 권장사항:
PHP 및 매개변수 주석을 사용하여 Beanstalkd를 작동하는 방법
PHP로 구현된 인트라넷 침투 애플리케이션 Spike가 재구성되었습니다
위 내용은 PHP Redis 잠금 및 잠금 해제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!