Kiedy używać WYBIERZ… DO AKTUALIZACJI?
Pomóż mi zrozumieć sprawę użyciaSELECT ... FOR UPDATE
.
Pytanie 1: Czy następujący przykład jest dobrym przykładem, kiedySELECT ... FOR UPDATE
należy użyć?
Dany:
pokoje [id]tagi [id, nazwa]room_tags [room_id, tag_id]id_ pokojowy i id_ tagu to klucze obceAplikacja chce wyświetlić listę wszystkich pokoi i ich tagów, ale musi rozróżnić pokoje bez tagów w porównaniu z pokojami, które zostały usunięte. Jeśli opcja SELECT ... FOR UPDATE nie jest używana, może się zdarzyć:
Początkowo:pokoje zawierają[id = 1]
zawiera tagi[id = 1, name = 'cats']
zawiera znaczniki pokoju[room_id = 1, tag_id = 1]
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 powinienSELECT id FROM rooms FOR UPDATE
, zapobiegając w ten sposób usunięciu wątku 2rooms
dopóki wątek 1 nie zostanie ukończony. Czy to jest poprawne?
pytanie 2: Kiedy należy użyćSERIALIZABLE
izolacja transakcji aREAD_COMMITTED
zSELECT ... FOR UPDATE
?
Oczekuje się, że odpowiedzi będą przenośne (nie dotyczą konkretnej bazy danych). Jeśli to niemożliwe, wyjaśnij dlaczego.