Proszę, pomóż mi zrozumieć przypadek użycia SELECT ... FOR UPDATE.
Pytanie 1 : Czy poniższy przykład jest dobrym przykładem, kiedy SELECT ... FOR UPDATEnależy stosować?
Dany:
- pokoje [id]
- tagi [identyfikator, nazwa]
- room_tags [room_id, tag_id]
- room_id i tag_id to klucze obce
Aplikacja chce wyświetlić wszystkie pokoje i ich tagi, ale musi rozróżnić pokoje bez tagów od tych, które zostały usunięte. Jeśli SELECT ... FOR UPDATE nie jest używany, może się zdarzyć:
- Początkowo:
- pokoje zawiera
[id = 1] - tagi zawiera
[id = 1, name = 'cats'] - room_tags zawiera
[room_id = 1, tag_id = 1]
- pokoje zawiera
- Wątek 1:
SELECT id FROM rooms;returns [id = 1]
- Wątek 2:
DELETE FROM room_tags WHERE room_id = 1; - Wątek 2:
DELETE FROM rooms WHERE id = 1; - Wątek 2: [zatwierdza transakcję]
- Wątek 1:
SELECT tags.name FROM room_tags, tags WHERE room_tags.tag_id = 1 AND tags.id = room_tags.tag_id;- zwraca pustą listę
Teraz wątek 1 uważa, że pokój 1 nie ma tagów, ale w rzeczywistości pokój został usunięty. Aby rozwiązać ten problem, Wątek 1 powinien SELECT id FROM rooms FOR UPDATEzapobiegać usuwaniu wątku 2 od roomsmomentu zakończenia Wątku 1. Czy to jest poprawne?
Pytanie 2 : Kiedy należy używać SERIALIZABLEizolacji transakcji, a READ_COMMITTEDkiedy z SELECT ... FOR UPDATE?
Odpowiedzi powinny być przenośne (nie specyficzne dla bazy danych). Jeśli to niemożliwe, wyjaśnij dlaczego.
REPEATABLE_READa READ_COMMITTEDnawet opcje przenośne? Jedyne wyniki, które otrzymuję, dotyczą serwera MSSQL
READ COMMITTEDtrybu nie definiuje, czy rzeczywiście zobaczysz rekordy zatwierdzone przez inną transakcję: zapewnia tylko, że nigdy nie zobaczysz niezatwierdzonych rekordów.
select ... for updateNa roomswciąż pozwalają room_tagsbyć usunięte, ponieważ są osobne tabele. Czy chodziło Ci o pytanie, czy for updateklauzula zapobiegnie usunięciom rooms?