-1

次の仮定の状況で何が起こるか知りたいです。2 人の教師がまったく同じクラスを同じ生徒に教えているとしましょう。2 人とも、生徒のボブの成績を更新したいと考えています。ボブの現在の平均は 60% で、教師 1 はボブが 70% を獲得したテストで平均を更新したいと考えており、教師 2 は彼が 40% を獲得したテストで平均を更新したいと考えています。

100 万分の 1 の確率で 2 人の教師が同時に更新ボタンを押した場合、正確に一瞬で正確に同時に、何が起こるでしょうか? それはエラー メッセージを表示しますか? php または mysql は魔法のように更新をキューに入れますか? 最初のスコアのみがボブの平均を更新し、2 番目のユーザーはエラーを受け取りますか?

編集:私の懸念は、最初のユーザーが値を編集した後に2番目のユーザーが値を取得する必要があることです。レコードを取得してからphpで計算を行い、レコードを再度更新することを考えていましたが、この状況ではどうすれば確実に2 番目のユーザーが 60% ではなく 65% の値をフェッチしますが、これはトランザクションで実行できますか?

4

5 に答える 5

3

同時にアクションを実行することはできません。マシンが同じ情報を同時に書き込むことは物理的に不可能であるため、常にわずかな違いが生じます。マイクロ秒以下の問題かもしれませんが、違いはそこにあります。

通常の解決策の 1 つは、WHERE句にそのようなデータを追加し、更新が行われたかどうかを確認することです。

UPDATE students SET `avg` = '70' WHERE id=<some-id> AND `avg` = '60';

ただし、平均のようなものは通常、この方法で更新しないのが最善です。別の学生スコアテーブルを用意し、学生ごとにそれらのレコードの平均を自分で計算します (必要に応じて、学生テーブルに「キャッシュ」することもできます)。

于 2012-06-19T11:28:15.070 に答える
2

どちらも通過し、最後に処理されたものが新しい値になります。データベース システムによる一貫性の保証により、データが破損することはありませんが、これは計算された値であるため、誤った データが取得される可能性があります。

この平均は、他のテーブルのデータに基づいて計算された値であると思われます。その場合は、すべての作業を 1 つのトランザクションで実行してください。新しいテスト スコアをテーブルに追加し、データベースに平均を計算させ、結果を 2 番目のテーブルに直接挿入します。そうすれば、結果が正しいことが保証される 、トランザクションが失敗します。これには、トランザクションをサポートするストレージ エンジン (InnoDB など) が必要です。

于 2012-06-19T11:28:36.630 に答える
1

悲観的ロックとトランザクションは、ここでの話の半分にすぎません。データベースは行ロックを解除しますが、これは、同じ行を変更しようとしている人が現在のトランザクションが完了するまで待たなければならないことを保証するだけです。私が防ぎたいケースは次のとおりです。

  1. 教師 a は課題を表示しますが、成績は表示されません。
  2. 教師 b は課題を表示しますが、成績は表示されません。
  3. 教師 a は 70 年生を割り当てます。
  4. 教師 b は 40 年生を割り当てます。

b が a をオーバーライドすることを意図していなかった可能性が非常に高いです。あなたの最善の保護は、楽観的ロックの何らかの形です。これは Wiki で 2 人が同時に編集を行うときに見られます。前の提出者の変更が誤って取り消される可能性があるため、後の提出者は編集を確認する必要があります。採点の場合、ユーザーに表示されていた古い成績を where 句に追加し、更新によって 1 行が変更されたことをアサートできます。

UPDATE GRADES SET SCORE=70 WHERE NAME='Jim' AND SCORE=0;
于 2012-06-19T11:44:15.627 に答える
1

データベースは行を順次更新します。クエリの 1 つが最初に実行され、行 (クエリによってはテーブル) がロックされ、最初のクエリが完了するまで次のクエリがキューに入れられます。

于 2012-06-19T11:25:10.553 に答える
1

操作がアトミックであれば問題はありません。そして、あなたのINSERTは. 両方の INSERT が実行されます。

ただし、非アトミック操作には注意してください。

そこにトランザクションが飛び込みます: http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_transaction

于 2012-06-19T11:26:10.220 に答える