背後のユースケースを理解するのを手伝ってくださいSELECT ... FOR UPDATE
。
質問1:次のSELECT ... FOR UPDATE
使用例は良い例ですか?
与えられた:
- 部屋[id]
- タグ[ID、名前]
- room_tags [room_id、tag_id]
- room_idとtag_idは外部キーです
アプリケーションは、すべての部屋とそのタグをリストする必要がありますが、タグのない部屋と削除された部屋を区別する必要があります。SELECT ... FOR UPDATEを使用しない場合、次のことが起こります。
- 最初は:
- 部屋には
[id = 1]
- タグに含まれる
[id = 1, name = 'cats']
- room_tagsには
[room_id = 1, tag_id = 1]
- 部屋には
- スレッド1:
SELECT id FROM rooms;
returns [id = 1]
- スレッド2:
DELETE FROM room_tags WHERE room_id = 1;
- スレッド2:
DELETE FROM rooms WHERE id = 1;
- スレッド2:[トランザクションをコミットします]
- スレッド1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
- 空のリストを返します
スレッド1は、部屋1にはタグがないと考えますが、実際には部屋は削除されています。この問題を解決するには、スレッド1をSELECT id FROM rooms FOR UPDATE
にする必要があります。これにより、rooms
スレッド1が完了するまでスレッド2が削除されなくなります。あれは正しいですか?
質問2:場合は1が使用するSERIALIZABLE
トランザクション分離が対READ_COMMITTED
とSELECT ... FOR UPDATE
?
回答は移植可能であることが期待されます(データベース固有ではありません)。それが不可能な場合は、その理由を説明してください。
REPEATABLE_READ
、READ_COMMITTED
さらにはポータブルオプションですか?私がこれらの結果を得る唯一の結果は、MSSQLサーバーに関するものです
READ COMMITTED
モードを設定しても、実際に別のトランザクションによってコミットされたレコードが表示されるかどうかは定義されません。コミットされていないレコードが表示されないことが確認されるだけです。
select ... for update
上はrooms
まだできるようになりますroom_tags
彼らは別々のテーブルであるため、削除します。for update
条項がからの削除を防止するかどうかを尋ねるかrooms
?