Допоможіть мені, будь ласка, зрозуміти приклад використання SELECT ... FOR UPDATE.
Запитання 1 : Чи наведений нижче приклад, коли SELECT ... FOR UPDATEслід використовувати?
Подано:
- кімнати [ід]
- теги [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, тим самим запобігаючи видаленню Нитки 2, roomsпоки Тема 1 не буде виконана. Це правильно?
Питання 2 : Коли слід використовувати SERIALIZABLEізоляції транзакцій по порівнянні READ_COMMITTEDз SELECT ... FOR UPDATE?
Очікується, що відповіді будуть портативними (не залежать від бази даних). Якщо це неможливо, поясніть, будь ласка, чому.
REPEATABLE_READі READ_COMMITTEDнавіть портативні варіанти? Єдині результати, які я отримую для них, - це сервер MSSQL
READ COMMITTEDрежиму не визначає, чи ви дійсно будете бачити записи, здійснені іншою транзакцією: це лише гарантує, що ви ніколи не побачите незапущені записи.
select ... for updateЗа - roomsяк і раніше дозволяють room_tagsбути видалено , оскільки вони є окремими таблицями. Ви хотіли запитати, чи for updateзапобіжить це застереження від видалення rooms?