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.
lockRedisKey("ABC"); CODE, DEN ICH NICHT GLEICHZEITIG AUSFÜHREN MÖCHTE! unlockRedisKey("ABC");
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?
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); }
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.
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(); }
您的“exit_time”太小。 我认为'$exit_time = $time + 10;'的含义10秒后将其关闭。 不过,设定的时间是微时间。
也许你可以替换 '$exit_time = $time + 10;'与“$exit_time = $time + 100000;”。 由谷歌翻译撰写
锁定工作正常。这只是锁定之间的代码崩溃并导致锁定无法释放:-)