Implement lock mechanism using PHPRedis
<p>I got the following two functions for locking the Redis key. I'm trying to prevent concurrent execution of a block of code using Redis. So what I did was use the following function to prevent different threads from executing the same code. </p>
<pre class="brush:php;toolbar:false;">lockRedisKey("ABC");
CODE THAT I DON'T WANT TO RUN CONCURRENTLY!
unlockRedisKey("ABC");</pre>
<p>Unfortunately, it doesn't seem to work and causes lockRedisKey() to loop infinitely until exit_time is reached. What could possibly go wrong? </p>
<pre class="brush:php;toolbar:false;">static public function lockRedisKey($key, $value = "true") {
$redis = RedisClient::getInstance();
$time = microtime(true);
$exit_time = $time 10;
$sleep = 10000;
do {
// Lock Redis with PX and NX
$lock = $redis->setnx("lock:" . $key, $value);
if ($lock == 1) {
$redis->expire("lock:" . $key, "10");
return true;
}
usleep($sleep);
} while (microtime(true) < $exit_time);
return false;
}
static public function unlockRedisKey($key) {
$redis = RedisClient::getInstance();
$redis->del("lock:" . $key);
}</pre>
<p>I knew I might face a deadlock, so I decided to use transactions, but I'm still facing this problem. </p>
<pre class="brush:php;toolbar:false;">static public function lockRedisKey($key, $value = "true") {
$redis = RedisClient::getInstance();
$time = microtime(true);
$exit_time = $time 10;
$sleep = 10000;
do {
// Lock Redis with PX and NX
$redis->multi();
$redis->set('lock:' . $key, $value, array('nx', 'ex' => 10));
$ret = $redis->exec();
if ($ret[0] == true) {
return true;
}
usleep($sleep);
} while (microtime(true) < $exit_time);
return false;
}
static public function unlockRedisKey($key) {
$redis = RedisClient::getInstance();
$redis->multi();
$redis->del("lock:" . $key);
$redis->exec();
}</pre></p>