Twój problem sprowadza się do pytania „jaka powinna być blokada synchronizacji” . Z twojego pytania wynika, że rezerwacja nie jest rezerwacją konkretnego przedmiotu. Załóżmy jednak, że użytkownik rezerwuje konkretny pokój hotelowy, więc musisz rozwiązać dwa problemy:
- zapobiegaj overbookingowi (np. rezerwacja tego samego dla dwóch osób)
- zapobiegaj błędnym obliczeniom stanu konta równoległego
Kiedy więc użytkownik dojdzie do momentu, w którym ma zamiar nacisnąć potwierdź przycisk, to możliwy scenariusz, który możesz wdrożyć:
-
rozpocznij transakcję
-
zablokuj wpis użytkownika, aby równoległe procesy były blokowane
SELECT * FROM user FOR UPDATE WHERE id = :id
-
ponownie sprawdź saldo konta i zrzuć wyjątek / wycofanie, jeśli nie ma wystarczających środków
-
zablokuj przedmiot do zarezerwowania, aby zapobiec przepełnieniu
SELECT * FROM room FOR UPDATE WHERE id = :id
-
ponownie sprawdź dostępność rezerwacji i zrzuć wyjątek / wycofanie, jeśli pozycja jest już zarezerwowana
-
utwórz wpis rezerwacji i odejmij środki z konta użytkownika
-
zatwierdź transakcję (wszystkie blokady zostaną zwolnione)
Jeśli w Twoim przypadku nie musisz sprawdzać, czy nie ma overbookingu, po prostu pomiń / zignoruj kroki 4 i 5.