Wyobraź sobie wtorek, godzinę 11:30. Dwie osoby otwierają ten sam formularz. Obie widzą wolny termin i niemal jednocześnie klikają „Rezerwuję”. Jeśli aplikacja sprawdzi dostępność, a dopiero chwilę później osobno zapisze wybór, obie kontrole mogą zwrócić „wolne”. To klasyczny wyścig między odczytem a zapisem.

Nie da się rozwiązać go samym przyciskiem, animacją ładowania ani blokadą w przeglądarce. Każda osoba ma przecież własną przeglądarkę. Decyzja, kto dostał termin, musi zapaść w miejscu wspólnym dla wszystkich żądań.

Kalendarz jest obietnicą warunkową

Lista wolnych godzin pomaga wybrać, ale od chwili jej pobrania stan może się zmienić. Dlatego po kliknięciu nie należy od razu wyświetlać potwierdzenia. Najpierw system próbuje zapisać rezerwację, a dopiero po udanym zapisie pokazuje wynik. Gdy termin właśnie zajął ktoś inny, odpowiedź musi powiedzieć to wprost i zaproponować ponowny wybór.

Ważne są również stany pośrednie. Przycisk może chwilowo pokazać „Sprawdzam termin…”, żeby użytkownik nie wysłał tego samego formularza kilka razy. To poprawia interfejs, ale nie zastępuje zabezpieczenia zapisu.

Reguła powinna mieszkać przy danych

Dla prostych wizyt o stałych godzinach można wyrazić zasadę jako unikalność kombinacji zasobu i terminu, na przykład prowadzący + data + godzina. Dokumentacja PostgreSQL opisuje ograniczenia UNIQUE, które pilnują unikalności także wtedy, gdy dwa żądania docierają równocześnie. Aplikacja próbuje zapisać termin i obsługuje konflikt jako spodziewany wynik biznesowy.

Jeśli rezerwacje mogą mieć różną długość i zachodzić na siebie częściowo, sama unikalność początku nie wystarczy. Wtedy trzeba modelować przedziały czasu i dobrać regułę bez nakładania się zakresów. PostgreSQL opisuje również ograniczenia wykluczające; wybór konkretnej konstrukcji zależy od modelu danych. Nie ma sensu nazywać pojedynczego indeksu rozwiązaniem każdego kalendarza.

Transakcja porządkuje kilka zmian naraz

Zapis terminu często pociąga za sobą utworzenie rezerwacji, zmianę statusu i przygotowanie potwierdzenia. Te kroki trzeba zaprojektować tak, aby błąd w połowie nie zostawił danych w sprzecznym stanie. Opis izolacji transakcji pokazuje, dlaczego równoczesne operacje mogą widzieć różne stany i dlaczego poziom izolacji wpływa na wynik.

E-mail najlepiej traktować jako powiadomienie o udanym zapisie, a nie dowód, że termin istnieje. Gdy wysyłka wiadomości się nie uda, rezerwacja może nadal być ważna. Użytkownik powinien móc sprawdzić jej stan w aplikacji, zamiast zgadywać na podstawie skrzynki odbiorczej.

Co sprawdzić przed publikacją

Test dwóch równoczesnych żądań do tego samego terminu jest cenniejszy niż dziesięć spokojnych kliknięć po kolei. Oczekiwany wynik: jedna rezerwacja, jedno czytelne odrzucenie, żadnych podwójnych potwierdzeń. Następnie sprawdziłbym ponowne wysłanie formularza po utracie połączenia, zmianę strefy czasowej, anulowanie i zwolnienie terminu.

Tak wygląda mniej widowiskowa część projektowania aplikacji: ekran ma być prosty, ale reguły muszą wytrzymać rzeczywiste zachowanie ludzi i sieci. Właśnie dzięki temu użytkownik może zaufać przyciskowi „Rezerwuję”.

Źródła i dalsza lektura

  1. postgresql.org
  2. postgresql.org

Zobacz też

Jak buduję aplikacje do obsługi klientów i zleceń

Masz proces, który nie mieści się już w arkuszu? Opisz, kto z niego korzysta i co dziś zajmuje najwięcej czasu.

Opisz swój proces
Masz pytanie dotyczące swojego projektu?Porozmawiajmy