Когда использовать SELECT… ДЛЯ ОБНОВЛЕНИЯ?
Пожалуйста, помогите мне понять сценарий использованияSELECT ... FOR UPDATE
.
Question 1: Является ли следующий хороший пример того, когдаSELECT ... FOR UPDATE
должен быть использован?
Дано:
rooms[id] tags[id, name] room_tags[room_id, tag_id] room_id and tag_id are foreign keysПриложение хочет перечислить все комнаты и их теги, но необходимо различать комнаты без тегов и комнаты, которые были удалены. Если SELECT ... FOR UPDATE не используется, то может произойти следующее:
Initially: rooms contains[id = 1]
tags contains [id = 1, name = 'cats']
room_tags contains [room_id = 1, tag_id = 1]
Thread 1: SELECT id FROM rooms;
returns [id = 1]
Thread 2: DELETE FROM room_tags WHERE room_id = 1;
Thread 2: DELETE FROM rooms WHERE id = 1;
Thread 2: [commits the transaction]
Thread 1: SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;
returns an empty list
Теперь тема 1 считает, что в комнате 1 нет тегов, но в действительности эта комната была удалена. Чтобы решить эту проблему, поток 1 долженSELECT id FROM rooms FOR UPDATE
тем самым предотвращая удаление темы 2 изrooms
пока не закончится тема 1. Это верно?
Question 2: Когда следует использоватьSERIALIZABLE
изоляция транзакции отREAD_COMMITTED
сSELECT ... FOR UPDATE
?
Ожидается, что ответы будут переносимыми (не зависящими от базы данных). Если это невозможно, пожалуйста, объясните, почему.