mam jakiś kod Rails ActiveRecord, który wygląda tak:Rails ActiveRecord - jak mogę zablokować tabelę do czytania?
new_account_number = Model.maximum(:account_number)
# Some processing that usually involves incrementing
# the new account number by one.
Model.create(foo: 12, bar: 34, account_number: new_account_number)
Ten kod działa poprawnie na własną rękę, ale mam pewne zadania w tle, które są przetwarzane przez pracowników DelayedJob. Jest dwóch pracowników i jeśli obydwoje zaczną przetwarzać partię zadań, które zajmują się tym kodem, kończą tworzenie nowych rekordów Model
, które mają ten sam numer konta, ze względu na opóźnienie pomiędzy znalezieniem maksimum a utworzeniem nowego rekordu z jeszcze wyższym poziomem numer konta.
Na razie rozwiązałem go, dodając ograniczenie unikalności na poziomie bazy danych do tabeli modeli, a następnie ponowić próbę, ponownie wybierając maksimum w przypadku, gdy to ograniczenie wyzwoli wyjątek.
Jednak to wygląda jak włamanie.
Dodawanie auto inkrementacji na poziomie bazy danych do kolumny account_number
nie jest opcją, ponieważ przypisywanie przypisów do konta oznacza więcej niż tylko inkrementację.
Idealnie chciałbym zablokować tabelę do czytania, więc żaden inny nie może wykonać kwerendy maksymalnej selekcji względem tabeli, dopóki nie skończę. Jednak nie jestem pewien, jak to osiągnąć. Używam PostgreSQL.
Ograniczenia nie są hackami, ręczne blokowanie tabel jest hakerem. –