PHPRedisを使用したロック機構の実装
P粉515066518
2023-08-28 18:33:09
<p>Redis キーをロックするための次の 2 つの関数を取得しました。 Redis を使用してコード ブロックの同時実行を防止しようとしています。そこで私がやったのは、次の関数を使用して、異なるスレッドが同じコードを実行しないようにすることでした。 </p>
<pre class="brush:php;toolbar:false;">lockRedisKey("ABC");
同時に実行したくないコードです。
unlockRedisKey("ABC");</pre>
<p>残念ながら、これは機能しないようで、 exit_time に達するまで lockRedisKey() が無限ループします。何が問題になる可能性がありますか? </p>
<pre class="brush:php;toolbar:false;">static public function lockRedisKey($key, $value = "true") {
$redis = RedisClient::getInstance();
$time = マイクロタイム(true);
$exit_time = $time 10;
$sleep = 10000;
する {
// PX および NX で Redis をロックする
$lock = $redis->setnx("lock:" . $key, $value);
if ($lock == 1) {
$redis->expire("lock:" . $key, "10");
true を返します。
}
usleep($sleep);
while (microtime(true) < $exit_time);
false を返します。
}
静的パブリック関数unlockRedisKey($key) {
$redis = RedisClient::getInstance();
$redis->del("lock:" . $key);
}</pre>
<p>デッドロックに直面する可能性があることがわかっていたので、トランザクションを使用することにしましたが、依然としてこの問題に直面しています。 </p>
<pre class="brush:php;toolbar:false;">static public function lockRedisKey($key, $value = "true") {
$redis = RedisClient::getInstance();
$time = マイクロタイム(true);
$exit_time = $time 10;
$sleep = 10000;
する {
// PX および NX で Redis をロックする
$redis->multi();
$redis->set('lock:' . $key, $value, array('nx', 'ex' => 10));
$ret = $redis->exec();
if ($ret[0] == true) {
true を返します。
}
usleep($sleep);
while (microtime(true) < $exit_time);
false を返します。
}
静的パブリック関数unlockRedisKey($key) {
$redis = RedisClient::getInstance();
$redis->multi();
$redis->del("lock:" . $key);
$redis->exec();
}</pre></p>
「exit_time」が小さすぎます。 $exit_time = $time 10; は 10 秒後に閉じることを意味すると思います。 ただし、設定時間はマイクロタイムです。
「$exit_time = $time 10;」を「$exit_time = $time 100000;」に置き換えることができるかもしれません。 Google 翻訳によって書かれました
ロックは正常に機能します。これはロック間のコードをクラッシュさせるだけで、ロックが解放されなくなります :-)