最近フラッシュセールイベントを行っていたのですが、パフォーマンスと応答速度の観点からredisを使用しました。書いているときは、超常現象を防ぐために特に注意を払っていましたが、Redis理論に基づいた楽観的ロックを使用していましたが、それでも非常に混乱しました。具体的なコードは次のとおりです:
リーリー最近フラッシュセールイベントを行っていたのですが、パフォーマンスと応答速度の観点からredisを使用しました。書いているときは、超常現象を防ぐために特に注意を払っていましたが、Redis理論に基づいた楽観的ロックを使用していましたが、それでも非常に混乱しました。具体的なコードは次のとおりです:
リーリー
このコードは、同時実行性が高い状況では依然として過剰に販売されると思います。仮定します: 賞品が 1 つしか残っていない場合、3 人が同時に実行し $redis->watch("mywatchkey")
得られたデータが 99 であった場合、売られすぎ現象が発生します。
はシングルスレッド読み取りであるため、最も単純なキュー実装を使用しましょう。 redis
キューに書き込みます award:100
// 長さ 100 のリスト。値は賞品を獲得するかどうかを決定するためにのみ使用されますredis
队列award:100
sleep(5);
あなたの会社はまだ人材を受け入れていますか?
この状況について考えてください。
mywatchkey=99
ユーザー A が mywatchkey をリクエストし、99 を取得します。
ユーザー B が mywatchkey をリクエストし、99 を取得します。
A と B のリクエストが完了したら、mywatchkey は何になるべきですか? 。 101、それとも100?
これは典型的な Check-then-Act エラーです
まず最初に、このコードの「売られすぎ」の結果が $mywatchkey > 100 であるかどうかをお聞きします (それは不可能だと思います)
または、$mywatchkey = 100 の場合、2 つのページが同時に表示され、「購入に成功しました!」
これについてはわかりません コードはテストされていますが、次の状況になるかどうかを推測しています:
2.セッションB: mywatchkeyの処理後、この時点ではmywatchkey=100ですが、セッションAの後続の操作には影響しません
さらに 2 つの接続を追加して見てください、何か得られるかもしれません
redis のトランザクションと監視ステートメント
redis-watch-multi-exec-by-one-client
この問題を根本的に解決したい場合は、まず勉強してください:
1.ロックします。
2. 従来のデータベーストランザクション。
次に、Redis と従来のデータベースの違いを学びます。