PHP 5.4.0 アプリケーション (IIS、FastCGI、非スレッドセーフ) で、2 人がデータベース内の同じテーブルをまったく同時に同じコードを実行して更新し、うっかりお互いのデータを台無しにしてしまう可能性はありますか?
私が質問する理由は、説明のつかないデータの不具合が時折見られるためです。最近のケースでは、別の顧客が同じテーブルをまったく同時に更新したことがわかりました。
私の質問のパート 2 は、これが実際に起こっている場合、どうすれば防止できるのでしょうか?
PHP 5.4.0 アプリケーション (IIS、FastCGI、非スレッドセーフ) で、2 人がデータベース内の同じテーブルをまったく同時に同じコードを実行して更新し、うっかりお互いのデータを台無しにしてしまう可能性はありますか?
私が質問する理由は、説明のつかないデータの不具合が時折見られるためです。最近のケースでは、別の顧客が同じテーブルをまったく同時に更新したことがわかりました。
私の質問のパート 2 は、これが実際に起こっている場合、どうすれば防止できるのでしょうか?
トランザクションを使用せずに各リクエストで複数の SQL ステートメントを実行している場合、その可能性は非常に高くなります。SQL ステートメントはアトミックであり、トランザクション ラップされた一連のステートメントと同様に、「グリッチ」が発生することはありません。
また、SQL 以外の場所 (フラット ファイルなど) で異なるリクエスト間で状態を共有している場合、控えめに言っても、明らかにスレッド セーフが損なわれます。
パート 2: トランザクションを使用する :)
PHP がスレッドセーフでないため、「お互いのデータを台無しにする」ことはできません。Apache の設定を準備/作成している場合 (例: を使用SetLocale
)、または共有情報を同時に更新するようにプログラムしている場合 (例: フラットファイル、アマダムが言うように)。
MySQL などのほとんどの通常のプロセス、GET パラメータの読み取りなどは影響を受けません。
したがって、問題がロケールにない限り、それはスレッド設定ではなくコードになります。
SetLocale を使用している場合、トランザクションやその他のメソッドは何の違いもありません。ラウンドをプログラムできる他のもの。
並行アクション用にプログラムしていない場合、データを台無しにする可能性があります。これは、スレッド セーフでも非スレッド セーフでも発生する可能性があります。「スレッドセーフ」であっても、異なる速度と順序で並行スレッドを処理できることに注意してください。
以下は危険な例です。
ステートメントは、「ユーザー 1」がすべてを実行し、その後に「ユーザー 2」が続くことで処理できます (理想的で、どのようにプログラムしたか)。しかし同様に、「ユーザー 1」が「a」と「b」を実行し、続いて「ユーザー 2」がすべてを実行し、次に「ユーザー 1」が「c」を実行します。この場合、「ユーザー 2」は「ユーザー 1」を上書きします。 " 書きました。
(繰り返しますが、これは PHP の「非スレッドセーフ」とは関係ありません。)
この後者の問題を回避する方法:
可能であれば、3 番目のオプションが最適です。テーブルのロックが乱雑になり、トランザクションが問題を解決しないことがあります。