テーブルの一貫した更新を実行するプログラムタスクがあります。簡単にするために、アイデアを示すためだけにダミー テーブルについて説明します。と の 2 つのテーブルがuser
ありnote
ます。
note
には(id
主キーの自動インクリメント) とuser_id
(外部キー)、number
およびがありnext_number
ます。
はnumber
、ユーザーのメモの番号です。は、これが最新のユーザーのメモである場合とnext_number
等しく0
なるか、次のユーザーのメモの数と等しくなる可能性があります (C++ リンク リストの次のノードへのポインタなど)。
したがって、各ユーザーには 1 から n までの番号が付けられたメモがあります。
現在、いくつかの 2 つのプロセス ( Proc1とProc2note
)で、同じユーザーのテーブルに行を挿入する必要があります。
そのため、各プロセスはトランザクションを開始し、number
最新のユーザーのメモを取得してから、他のアクションを実行し、number
1 にインクリメントされた新しい行を挿入します。
両方のプロセス ( Proc1とProc2 ) がトランザクション内で同じものを取得する可能性はありますか (たとえば、最初のプロセスがステートメントを実行してから、2 番目のプロセスがそのステートメントを実行します)。number
SELECT
INSERT
UPDATE
例えば:
- Proc1:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 取得した番号5 - Proc2:
SELECT number FROM note WHERE user_id = 1 AND next_number = 0
- 番号5を取得 - Proc1:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc1 note'
- Proc2:
INSERT INTO note SET number = 6, next_number = 0, user_id = 1, text = 'Proc2 note'
- Proc1:
UPDATE note SET next_number = 6 WHERE number = 5
- Proc2:
UPDATE note SET next_number = 6 WHERE number = 5
- Proc1: Proc1 のトランザクションをコミットしています
- Proc2: Proc2 のトランザクションのコミット
可能であれば、これを回避するにはどうすればよいですか?問題はSELECT ... FOR UPDATE
解決しますか?
更新 - 私の質問を簡素化する
したがって、一般的な質問は、プロセスがトランザクションを開始した場合、現在のトランザクションが処理している行と他の MySQL セッションがやり取りできないようにする方法です。