Implementing Lock and Unlock Operations with PHP and Redis
This article explains how to use PHP and Redis to create a blocking lock for a game room, safely add users while preventing dirty reads, and release the lock atomically with a Lua script, providing complete code examples and practical tips.
This article introduces a method for implementing lock and unlock operations using PHP and Redis, which can be useful for preventing concurrent dirty‑read issues in room‑based multiplayer games.
Business background
When multiple clients try to add a user to a game room simultaneously, the RoomUsers data can become inconsistent due to concurrent reads.
Solution overview
The approach is to lock the room so that only one client can modify it at a time (a blocking lock). After the operation finishes, the lock is released.
Locking implementation
Redis provides several locking commands (INCR, SET, SETNX, HSETNX). This example uses the SET command with the NX and EX options.
$roomId = $_GET['roomId'];
$user = $_GET['user']; // 'Zhang San'
$key = "LockRoom:{$roomId}";
$value = $roomId . uniqid();
$ex = 3;
// Try to acquire the lock; repeat until successful
while (true) {
$res = $this->redis->set($key, $value, ['nx', 'ex' => $ex]);
if ($res) { break; }
usleep(5000);
}
// Add the user to the room
$roomUsers = $this->redis->get("Room:{$roomId}:Users"); // e.g., ['Li Si', 'Wang Wu']
$roomUsers[] = $user;
$this->redis->set("Room:{$roomId}:Users", $roomUsers); // now includes the new userUnlocking implementation
After the operation, the lock must be released. Directly deleting the key can be unsafe because another client might have acquired a new lock after the original one expired. To avoid this race condition, a Lua script is used to delete the key only if its value matches the one that was set when the lock was acquired.
// Lua script for safe unlock
$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);Additional references include articles on proper Redis lock release and the PhpRedis documentation for set() and eval() functions. Note that using Lua scripts may require enabling shell_exec() and related functions in php.ini. The code provided is for reference only.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
php Courses
php中文网's platform for the latest courses and technical articles, helping PHP learners advance quickly.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
