Dzień dobry,
chciałbym dodać jedną lub wiele (maks. kilkadziesiąt) rezerwacji do sali, tak, żeby nie wywoływały one konfliktu czasowego z już istniejącymi.
Każda rezerwacja posiada m.in: room_id (foreign key), begin_time, end_time
Początkowo wydawało mi się, że wystarczy sprawdzić, czy istnieje zachodzący czasowo wiersz, a jeśli nie, to dodać rezerwację. Uzmysłowiłem sobie jednak, że przy dużym obciążeniu może się zdarzyć, że klient1 sprawdzi brak konfliktu, a następnie klient2 dostanie brak konfliktu, jeżeli klient1 nie zdąży jeszcze wykonać INSERT i ostatecznie obie zachodzące na siebie rezerwacje trafią do tabeli. Z tego, co wygooglowałem, można się przed tym zabezpieczyć na dwa sposoby wykorzystujące transakcje:
A. Wykonać SELECT … FOR UPDATE
na wierszu sali, co jak rozumiem zablokuje innych klientów, na czas operacji, a następnie przed dodaniem każdej rezerwacji (INSERT) wykonywać zapytanie sprawdzające (SELECT), czy nie ma konfliktu. W przypadku konfliktu nie dodawać.
B. Dodawać rezerwacje po kolei (INSERT) i sprawdzać czy poza dodanym wierszem, jest jeszcze jakiś inny, który wywołuje konflikt (SELECT), jeśli tak, to ROLLBACK
.
Mam dwa pytania:
-
Które podejście jest lepsze?
-
Czy w takiej sytuacji potrzebna jest jakaś optymalizacja, jeśli chodzi o ilość zapytań do bazy? Np. Multiple INSERT oraz SELECT z przerośniętą klauzulą WHERE z warunkami czasowymi dla wszystkich dodawanych wierszy?