2011-02-06 8 views
1

私は、データキャッシュ機能を備えたPHPサイト用の新しいエンジンを開発しています。今私はこれらのスクリプト間の干渉が可能かどうか疑問に思っています。次の例を考えてみましょう。データキャッシングが干渉を引き起こす可能性がありますか?

多くのユーザーが写真関連のWebサイトにアクセスし、2人がほぼ同じ時間に2つのスクリプトを実行しているとします。

スクリプト1は、 'FooBar'という名前のユーザーとそのすべての写真をデータベースから削除します。

スクリプト2は、写真nr 12345(FooBar製)を表示します。

  1. (スクリプト1)ユーザー 'FooBar'が存在するかどうかを確認します。そのIDを変数$idに格納します。
  2. (スクリプト2)写真nr 12345が存在するかどうかを確認します。店主IDを変数$ownerに格納します。
  3. (スクリプト1)query("DELETE FROM users WHERE id='$id' ");
  4. (スクリプト2)query("SELECT name FROM users WHERE id='$owner' ");//エラーここ
  5. (スクリプト1)query("DELETE FROM photos WHERE owner='$id' ");

私達が見たように、スクリプト2は、写真が存在することを検出したが、その所有者は既に削除されています。

質問はです:PHPスクリプトが順番に処理されていますか?(提示されたシナリオは不可能です)そうでない場合は、1つのスクリプトで複数のクエリを送信するときに、そのようなエラーを防ぐために何ができますか?

ありがとうございました。


ありがとうございました。提示された風景は単なる例であり、私はこれがより良い方法で行えることを知っています。だから、大規模なウェブサイトを作成するとき、私は常にランタイム中にデータを変更することができることを認識している必要があります。

しかし、この方法では、PHPの変数に格納されている情報を信頼できません。このような問題にどのように対処していますか? 1つのクエリ内のすべてのデータを更新または取得しますか?

+0

ステップ4は「エラー」ではないはずです。レコードが返されていないことを検出し、ユーザーに404を表示する必要があります。 – meagar

答えて

1

提示されたシナリオが可能です。私があなたがすることができる唯一のことは、このイベントのためのエラーをコードすることです:あなたが示すように、クエリ4は有効な所有者を返しません。ここではいくつかのことができますが、これは例に過ぎません。

  • オーナーネームを組み合わせたクエリで返して、画像の所有者が見つかった場合は少なくともその名前を表示することができます(ポイント2)。後であなたがもっと多くを見せたいならば、所有者が元気ではないことを返すだけで済むでしょう。それは起こったことです(それは負荷の間で削除されています)ので、ユーザーにとって少し奇妙であっても、彼はそれに対処しなければなりません:)
  • ちょうどポイント4のエラーを、前の例のあなたはすぐに結果を得ましたが、それはなくなってしまいました。だからあなたは "ユーザーをロードできませんでした"とかそのようなものを返します。
1

実際、競合状態が可能です。

のユーザーを削除するには、削除スクリプトで奇妙なものが私に当たって、さんの写真よりも前に表示されます。ユーザーの削除後、写真の削除前に何かが消えた場合、dbにはまだ孤立した写真が残っています。通常、トランザクションは(InnoDBのような、それらをサポートするストレージエンジンを使用して)この問題を緩和します。

競合状態自体については、他のプロセスがそれらに同時にアクセスするのを防ぐために行ロックを使用する技術があると私は信じています。

[いくつかの調査を行う機会があれば、詳細を記入します。これまでの簡単な調査では、'mysql row locking'には、トランザクションの影響を受ける行を実際に暗黙的にロックするエンジンがあることが示唆されています。しかし、そこに直接の経験がないと告白します。]

関連する問題