Heim  >  Fragen und Antworten  >  Hauptteil

Implementieren Sie den Sperrmechanismus mit PHPRedis

<p>Ich habe die folgenden zwei Funktionen zum Sperren des Redis-Schlüssels erhalten. Ich versuche, die gleichzeitige Ausführung eines Codeblocks mithilfe von Redis zu verhindern. Deshalb habe ich die folgende Funktion verwendet, um zu verhindern, dass verschiedene Threads denselben Code ausführen. </p> <pre class="brush:php;toolbar:false;">lockRedisKey("ABC"); CODE, DEN ICH NICHT GLEICHZEITIG AUSFÜHREN MÖCHTE! unlockRedisKey("ABC");</pre> <p>Leider scheint es nicht zu funktionieren und führt dazu, dass lockRedisKey() eine Endlosschleife durchführt, bis exit_time erreicht ist. Was könnte möglicherweise falsch laufen? </p> <pre class="brush:php;toolbar:false;">statische öffentliche Funktion lockRedisKey($key, $value = "true") { $redis = RedisClient::getInstance(); $time = microtime(true); $exit_time = $time + 10; $sleep = 10000; Tun { // Redis mit PX und NX sperren $lock = $redis->setnx("lock:" . $key, $value); if ($lock == 1) { $redis->expire("lock:" . $key, "10"); return true; } usleep($sleep); } while (microtime(true) < $exit_time); falsch zurückgeben; } statische öffentliche Funktion unlockRedisKey($key) { $redis = RedisClient::getInstance(); $redis->del("lock:" . $key); }</pre> <p>Ich wusste, dass es zu einem Deadlock kommen könnte, also habe ich mich für die Verwendung von Transaktionen entschieden, aber ich stehe immer noch vor diesem Problem. </p> <pre class="brush:php;toolbar:false;">statische öffentliche Funktion lockRedisKey($key, $value = "true") { $redis = RedisClient::getInstance(); $time = microtime(true); $exit_time = $time + 10; $sleep = 10000; Tun { // Redis mit PX und NX sperren $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); falsch zurückgeben; } statische öffentliche Funktion unlockRedisKey($key) { $redis = RedisClient::getInstance(); $redis->multi(); $redis->del("lock:" . $key); $redis->exec(); }</pre></p>
P粉515066518P粉515066518439 Tage vor621

Antworte allen(2)Ich werde antworten

  • P粉386318086

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

    您的“exit_time”太小。 我认为'$exit_time = $time + 10;'的含义10秒后将其关闭。 不过,设定的时间是微时间。

    也许你可以替换 '$exit_time = $time + 10;'与“$exit_time = $time + 100000;”。 由谷歌翻译撰写

    Antwort
    0
  • P粉336536706

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

    锁定工作正常。这只是锁定之间的代码崩溃并导致锁定无法释放:-)

    Antwort
    0
  • StornierenAntwort