0

条件に応じて、2 つの異なるテーブルに行を挿入しています。

たとえば、stories検討中の 2 つのフィールドで名前が付けられたテーブルがあるとします:
( story_id and comments_count)

および他の 2 つのテーブル:

  1. regcomments (comment_id, story_id, comment_text)
  2. unregcomments (comment_id, story_id, comment_text)

ここで、任意の に新しいコメントを挿入する前に、が 100 未満story_idかどうかを確認したいだけです。そうであれば、行を に挿入する必要があります。comments_countregcommentsunregcomments

これが私がそれを行った方法の疑似コードです:

select comments_count from stories where story_id = x
if comment_count<100
    insert into regcomments
else
    insert into unregcomments

複数のユーザーがこのスクリプトにアクセスしている場合、これが失敗する可能性はありますか? たとえば、ストーリーには 99 のコメントがあります。2 人のユーザーがこの関数をまったく同時に呼び出します。最初の選択クエリは両方に対して同時に実行され、両方とも 99 を取得します。したがって、両方の挿入が regcomments に対して行われ、regcomments のカウントが 101 になります。これは私のビジネス ルールに反します。誰もが、物事がどのように進むか、何らかの考えを持っています。または、このシナリオをどのように処理する必要があるかについてのアイデア。(なぜ私が2つのテーブルを使用しているのか聞かないでください:P とにかく)

4

2 に答える 2

0

はい、失敗する可能性があります。これは、10個のリクエストがすべてSQLクエリから99個のcomments_countを受け取る可能性があり、新しい行がregcommentsに挿入されるたびに、テーブルに109行が含まれるためです。

考えられる解決策の1つは、チェックロジックをSQLに移動することです(ロック/ミューテックスでストアドプロシージャを使用します)。

于 2013-02-04T19:53:15.807 に答える
0

テーブルに InnoDB エンジンを使用し、操作全体をトランザクションにラップします。InnoDB が並行性を処理します。挿入/更新ステートメントからのエラーを処理するコードを準備するだけです。他の操作の進行中に選択が実行されないようにするには、高い分離レベルを設定する必要があると思います。これが機能しない場合は、LOCK TABLE を使用する必要があるかもしれません。醜いですが、仕事をします。

于 2013-02-04T22:18:45.527 に答える