search

Home  >  Q&A  >  body text

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>
P粉515066518P粉515066518542 days ago691

reply all(2)I'll reply

  • P粉386318086

    P粉3863180862023-08-29 12:37:10

    Your "exit_time" is too small. I think $exit_time = $time 10; means close it after 10 seconds. However, the set time is micro time.

    Maybe you can replace '$exit_time = $time 10;' with '$exit_time = $time 100000;'. Written by Google Translate

    reply
    0
  • P粉336536706

    P粉3365367062023-08-29 11:16:33

    Locking works fine. This just crashes the code between locks and causes the lock to not be released :-)

    reply
    0
  • Cancelreply