ホームページ >バックエンド開発 >PHPチュートリアル >PHPのオプティミスティックロック原理の詳細な説明
1. ロック (同時実行制御) が必要なのはなぜですか?
マルチユーザー環境では、複数のユーザーが同じレコードを同時に更新する可能性があり、競合が発生する可能性があります。これは有名な同時実行性の問題です。
典型的な競合は次のとおりです:
1. 更新の損失: 1 つのトランザクションの更新により、他のトランザクションの更新結果が上書きされます。これは、いわゆる更新損失です。例: ユーザー A が値を 6 から 2 に変更し、ユーザー B が値を 2 から 6 に変更すると、ユーザー A は更新を失います。
2. ダーティ リード: ダーティ リードは、トランザクションが他の途中で完了したトランザクションの記録を読み取るときに発生します。たとえば、ユーザー A と B が見た値は両方とも 6 ですが、ユーザー B は値を 2 に変更しますが、ユーザー A が読み取った値は 6 のままです。
同時実行によって引き起こされるこれらの問題を解決するため。 同時実行制御メカニズムを導入する必要があります。
2. 同時実行制御メカニズム
ロック、つまり、選択したターゲットデータを他のプログラムによって変更できないようにロックします。
外部によって変更されるデータ (システムの現在のトランザクションや外部システムからのトランザクション処理を含む) に対する保守的な態度を指すため、データはデータ処理プロセス全体を通じてロックされた状態に保たれます
2オプティミスティック ロック: 同時実行性の競合は発生しないと想定し、操作の送信時にデータの整合性が侵害されているかどうかのみをチェックします。オプティミスティック ロックではダーティ リードの問題を解決できません。
3. 楽観的ロックの実装
データバージョン(Version)記録メカニズムを使用して実装されます。これは、楽観的ロックの最も一般的に使用される実装方法です。データバージョンとは何ですか?つまり、通常は数値の「バージョン」フィールドをデータベース テーブルに追加することによって、データにバージョン識別子を追加します。データを読み込む際には、データが更新されるたびにバージョンフィールドの値も合わせて読み出します。バージョン値は 1 ずつ増加します。更新を送信するとき、データベース テーブルの対応するレコードの現在のバージョン情報と、データベース テーブルの現在のバージョン番号が最初に取得したバージョン値とを比較します。初回は更新されます。それ以外の場合は、期限切れのデータとみなされます
1. データベーステーブルの設計
タスク
には、ID、値、バージョンの 3 つのフィールドがあります
2. 実装
1)最初にタスク テーブルのデータ (実際にはこのテーブル レコードにはフィールドが 1 つだけあります)、バージョンの値は versionValue
2) タスク テーブルの値フィールドを更新するたびに、競合を防ぐために、次のことが必要ですこれを行うには
update task set value = newValue, version = versionValue + 1 where version = versionValue ;
このステートメントが実行された場合にのみ、value フィールド値の更新が成功したことが示されます
2 つのノードがあると仮定しますノード A とノード B がタスク テーブルの値フィールドの値を更新するのはほぼ同時に、ノード A とノード B がタスク テーブルから読み取ったバージョン値は 2 であり、ノード A とノード B が値フィールドの値を更新するときです。 、両方とも更新タスク set value = newValue、version = 3 where version = 2; を実行します。実際には、SQL ステートメントを実行するノードは 1 つだけです。ノード A が正常に実行され、タスク テーブルのバージョン フィールドの値が実行されると仮定します。次に、ノード B が更新タスクを実行します。 set value = newValue、version = 3 where version = 2; この SQL ステートメントは実行されないため、タスク テーブルの更新時に競合が発生しません。
関連する推奨事項:
Redis でトランザクション メカニズムと楽観的ロックを実装する方法
以上がPHPのオプティミスティックロック原理の詳細な説明の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。