1

テーブルの一貫した更新を実行するプログラムタスクがあります。簡単にするために、アイデアを示すためだけにダミー テーブルについて説明します。と の 2 つのテーブルがuserありnoteます。

noteには(id主キーの自動インクリメント) とuser_id(外部キー)、numberおよびがありnext_numberます。
number、ユーザーのメモの番号です。は、これが最新のユーザーのメモである場合とnext_number等しく0なるか、次のユーザーのメモの数と等しくなる可能性があります (C++ リンク リストの次のノードへのポインタなど)。
したがって、各ユーザーには 1 から n までの番号が付けられたメモがあります。

現在、いくつかの 2 つのプロセス ( Proc1Proc2note )で、同じユーザーのテーブルに行を挿入する必要があります。

そのため、各プロセスはトランザクションを開始し、number最新のユーザーのメモを取得してから、他のアクションを実行し、number1 にインクリメントされた新しい行を挿入します。

両方のプロセス ( Proc1Proc2 ) がトランザクション内で同じものを取得する可能性はありますか (たとえば、最初のプロセスがステートメントを実行してから、2 番目のプロセスがそのステートメントを実行します)。numberSELECTINSERTUPDATE

例えば:

  1. Proc1: SELECT number FROM note WHERE user_id = 1 AND next_number = 0- 取得した番号5
  2. Proc2: SELECT number FROM note WHERE user_id = 1 AND next_number = 0- 番号5を取得
  3. Proc1:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
  4. Proc2:INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
  5. Proc1:UPDATE note SET next_number = 6 WHERE number = 5
  6. Proc2:UPDATE note SET next_number = 6 WHERE number = 5
  7. Proc1: Proc1 のトランザクションをコミットしています
  8. Proc2: Proc2 のトランザクションのコミット

可能であれば、これを回避するにはどうすればよいですか?問題はSELECT ... FOR UPDATE解決しますか?

更新 - 私の質問を簡素化する

したがって、一般的な質問は、プロセスがトランザクションを開始した場合、現在のトランザクションが処理している行と他の MySQL セッションがやり取りできないようにする方法です。

4

1 に答える 1

0

これをテストして正しいことを確認する必要がありますが、2 番目のSELECT ... LOCK IN SHARE MODEステートメントは最初のステートメントが完了するまでブロックする必要があります。これを暗黙的に設定する SERIALIZABLE トランザクション分離レベルも確認する必要があります。

于 2012-08-25T15:30:34.317 に答える