Proces dodawania nowego użytkownika w systemie, PHP i Postgresql

0

Hej

Piszę aplikację w PHP z wykorzystaniem bazy postgresql.

Zastanawiam się jak powinien wyglądać proces dodania nowego użytkownika w mojej aplikacji, tak aby nie wystąpiła hipotetyczna sytuacja w której dwie osoby chciałyby stworzyć użytkownika o takiej samej nazwie w tym samym czasie. Oczywiście zakładam, że user_name jest unique. Nie chciałbym również doprowadzić do sytuacji w której polecenie insert spowoduje wyrzucenie wyjątku, bo ktoś mnie ubiegł.

  1. BEGIN TRANSACTION;
  2. SELECT COUNT(user_name) FROM users WHERE user_name = 'user_name_from_form';
  3. Sprawdzam w skrypcie PHP czy COUNT(user_name) == 0 jeżeli tak to robię inserta.
  4. COMMIT;

Zastanawiam się czy wrzucenie tego w transakcje zapewni że INSERT nigdy się nie wywali.

Baza danych pracuje w standardowym trybie read commited.

Czy aby zapobiec takiej sytuacji muszę zablokować całą tabelę poleceniem SELECT * FROM users FOR UPDATE?

Dzięki za pomoc :D i Wasze doświadczenie.

0

Nic z tego. Read commited nie zabezpiecza się przed phantomami. Musiałbyś mieć tutaj poziom izolacji Serializable żeby wykluczyć sytuację że dwie transakcje będą dodawać nowe wiersze w tym samym czasie.

Read commited zabezpiecza cię tylko przed dirty readem - czyli nigdy nie zdarzy się tak że pobierzesz z bazy wartość która potem zostanie wycofana. Ale nadal możesz mieć problemy:

  • non-repeatable read - może się okazać że kilka razy odczytasz tą samą wartość a ona w międzyczasie się zmieni (ale będą to zmiany zakomitowane!)
  • phantom read - może się okazać że w czasie transakcji będzie ci przybywać wierszy (bo locki są założone na konkretne wiersze a nie na calą tabelę, ergo można do niej dodawać)
0

Czyli w takiej sytuacji najlepiej przechwycić errora i poprosić użytkownika aby jeszcze raz wypełnił formularz.

Myślę że taka sytuacja pewnie dość rzadko się zdarza.

1 użytkowników online, w tym zalogowanych: 0, gości: 1