PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Podwybór PostgreSQL i ActiveRecord dla warunków wyścigu

Twoje opcje to:

  • Uruchom w SERIALIZABLE izolacja. Transakcje współzależne zostaną przerwane po zatwierdzeniu, ponieważ wystąpiły niepowodzenie serializacji. Otrzymasz dużo spamu w dziennikach błędów i będziesz wykonywać wiele ponownych prób, ale będzie działać niezawodnie.

  • Zdefiniuj UNIQUE ograniczenie i ponowna próba w przypadku niepowodzenia, jak zauważyłeś. Takie same problemy jak powyżej.

  • Jeśli istnieje obiekt nadrzędny, możesz SELECT ... FOR UPDATE obiekt nadrzędny przed wykonaniem max zapytanie. W tym przypadku SELECT 1 FROM bar WHERE bar_id = $1 FOR UPDATE . Używasz bar jako blokada dla wszystkich foo s z tym bar_id . Możesz wtedy wiedzieć, że kontynuowanie jest bezpieczne, o ile każde zapytanie, które wykonuje przyrost licznika, robi to niezawodnie. To może działać całkiem dobrze.

    To nadal tworzy agregujące zapytanie dla każdego wywołania, które (na następną opcję) jest niepotrzebne, ale przynajmniej nie spamuje dziennika błędów, jak powyższe opcje.

  • Użyj stolika licznikowego. To właśnie bym zrobił. Albo w bar lub w tabeli bocznej, takiej jak bar_foo_counter , uzyskaj identyfikator wiersza za pomocą

    UPDATE bar_foo_counter SET counter = counter + 1
    WHERE bar_id = $1 RETURNING counter
    

    lub mniej wydajna opcja, jeśli Twój framework nie obsługuje RETURNING :

    SELECT counter FROM bar_foo_counter
    WHERE bar_id = $1 FOR UPDATE;
    
    UPDATE bar_foo_counter SET counter = $1;
    

    Następnie w tej samej transakcji , użyj wygenerowanego wiersza licznika jako number . Po zatwierdzeniu wiersz tabeli liczników dla tego bar_id zostanie odblokowany do użycia w następnym zapytaniu. Jeśli cofniesz, zmiana zostanie odrzucona.

Polecam podejście licznikowe, używając dedykowanej tabeli bocznej dla licznika zamiast dodawania kolumny do bar . Model jest czystszy i oznacza, że ​​w bar tworzysz mniej wzdęć aktualizacji , co może spowolnić zapytania do bar .




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak mogę zmienić wielkość liter dla każdej litery w ciągu za pomocą SQL?

  2. Próba skonstruowania zapytania PostgreSQL w celu wyodrębnienia z JSON wartości tekstowej w obiekcie, tablicy, obiekcie, tablicy, obiekcie

  3. Jaka jest żywotność przygotowanego oświadczenia po stronie serwera PostgreSQL

  4. Postgres nie mógł połączyć się z serwerem

  5. Numer listy zduplikowanych wartości