ホームページ >バックエンド開発 >PHPチュートリアル >Redisロックを解除する正しい方法
Redis は PHP の良い友達です。PHP でビジネスを記述する場合、同時に特定の動作を実行できるのは 1 人だけです。現時点ではロックを使用する必要があります。ロック方法はいくつかありますが、PHP ではメモリ内のロックを使用できず、データベースを使用してロックすることもできません。現時点では、ロック メカニズムとして redis を選択するのが一般的です。この記事では主に Redis のロックを解除する正しい方法を紹介し、皆様のお役に立てれば幸いです。
setnx
Redis でロックされている最も単純なデータ構造は文字列です。初期の頃、setnx はロック操作に一般的に使用されていました。このコマンドは、:lock が存在しない場合に val を設定するためのものでした。ロックのロックを解除するには、expir を使用することも忘れないでください。 del コマンドの疑似コードは次のとおりです:
if (Redis::setnx("my:lock", 1)) { Redis::expire("my:lock", 10); // ... do something Redis::del("my:lock") }
ここには実際には問題があります。問題は、setnx とexpired の間にクラッシュまたはその他の動作がある場合、ロックが解放されない可能性があることです。したがって、さらなる最適化ソリューションは、タイムスタンプをロックに保存することかもしれません。タイムスタンプの長さを決定します。
set
現在、ロックを実装するには set を直接使用することが公式に推奨されています。 set コマンドを使用して setnx を置き換えることができます。これは次のようになります
if (Redis::set("my:lock", 1, "nx", "ex", 10)) { ... do something Redis::del("my:lock") }
上記のコードは my:lock を 1 に設定します。ロックが存在しない場合に限り、有効期限はその後 10 に設定されます。設定が完了しました。
ロックを取得するメカニズムは正しいですが、del を直接使用してロックを削除するメカニズムは正しくありません。他の人のロックを誤って削除してしまう可能性があるためです。
たとえば、このロックを10秒間ロックしましたが、処理時間が10秒を超え、10秒でロックが自動的に期限切れになり、他の人によって奪われ、再ロックされました。この時点で、Redis::del を再度呼び出すと、他の人が作成したロックが削除されます。
公式には、ロックを解除するためのコマンドも記載されています。 lua スクリプトを使用し、最初に get を実行し、次に del を実行することをお勧めします。 プログラムは次のようになります。
$token = rand(1, 100000); function lock() { return Redis::set("my:lock", $token, "nx", "ex", 10); } function unlock() { $script = ` if redis.call("get",KEYS[1]) == ARGV[1] then return redis.call("del",KEYS[1]) else return 0 end ` return Redis::eval($script, "my:lock", $token) } if (lock()) { // do something unlock(); }
ここでのトークンは、ロック時の乱数です。 、redis に移動します。このトークンは my:lock に保存されています。ロックを解除するときは、まずロック内のトークンを取得します。一致しない場合は、ロックが以前に設定されたことを意味します。は、ロックが期限切れになったことを意味します。誰かが設定したものなので、何もするべきではありません。
つまり、setnx はもう使用せず、ロックの実装には set を直接使用してください。
関連する推奨事項:
php redis ロックを使用して同時アクセス クラスを制限する php redis ロックを使用して同時アクセス クラスを制限する例 php で redis を操作する一般的な方法のまとめ以上がRedisロックを解除する正しい方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。