2016-09-13 17 views
6

Myślę, że wyeliminowałem wszystko, ale nie jestem pewien, czy rozumiem OL na tyle, aby być pewnym. Ogólnie rzecz biorąc, załóżmy, że jesteście w zespole, aby informować foo na bieżąco. Jestem w jednym pokoju i decyduję się zaoszczędzić czas. Zaktualizuję foo. Więc zacząłem go aktualizować. Po chwili masz ten sam pomysł i logujesz się na stronę edycji, aby również ją zaktualizować. Co się stanie, jeśli skończę pierwszy? Co się stanie, jeśli skończysz pierwszy? W konfiguracji, w której nie działa, w jaki sposób odróżnia osobę edytującą od kogoś czytającego. Jeśli I catch i ponownie załadować, aby zaktualizować blokadę, tracę wszystkie moje zmiany, w jaki sposób jest to rozwiązane? W tym przypadku proste jest ponowne wykonanie aktualizacji, ale potencjalnie jest to część bardziej skomplikowanego obiektu formularza.Uzyskiwanie błędu "Stale object". Optymistyczne blokowanie: jak to działa?

Mój konkretny problem pojawił się, kiedy (najlepiej potrafię to zrozumieć) załadowałem jedną kopię w przeglądarce, później zapomniałem o niej, a następnie jeden w mojej konsoli (także blokada: 0?) Nie mógł zaktualizować tego w mojej konsoli nieaktualny błąd obiektu. Zauważyłem przeglądarkę. Zamknąłem moją konsolę. Próbowałem przeładować moją przeglądarkę i otrzymałem również nieaktualny błąd obiektu. Oto kod, który jest w braku:

=> 7:  self.update_attributes({ 
    8:   failed_view_attempts: self.failed_view_attempts += 1, 
    9:   failed_view_at: Time.now 
    10:  }) 
    11:  end 
(byebug) self 
#<Product id: 12... lock_version: 0> 

#=> ActiveRecord::StaleObjectError (Attempted to update a stale object: Product.) 

Czego próbowałem:

Aby sprawdzić, czy inny przypadek był załadowany dodałem puts "CALLED !!!!" w after_initialize zwrotnego, ale to tylko drukowane raz.

i sprawdzanie self.changed po ratowania od błędu i wrócić ["updated_at", "failed_view_attempts", "failed_view_at"]

Odpowiedz

1

trzeba ustawić domyślną lock_version kolumny do zera (0).

0

Optymistyczne blokowanie oparte jest na numerze wersji obiektu.

Czytanie i obiekt nie powinny w ogóle wpływać na numer wersji.

Jeśli spróbujesz zaktualizować jakiś obiekt, ten numer wersji jest porównywany (w sql faktycznie instrukcja aktualizacji jest używana na przykład "update ... where version = 1 and ...") i zwiększona w momencie aktualizacji.

Jeśli porównanie nie powiedzie się podczas próby aktualizacji, pojawi się błąd nieaktualnego obiektu. Oznacza to, że obiekt został zmodyfikowany przez kogoś innego podczas wprowadzania zmian.

Aby rozwiązać ten błąd, należy ponownie załadować obiekt, aby uzyskać aktualną wersję i ewentualnie połączyć zmiany ręcznie (przedstawiając użytkownikowi pewne informacje na ten temat, a użytkownik może na przykład zdecydować).

+0

Ale jeśli podczas edytowania ktoś dzwoni do instancji tego samego wiersza, aby ją przeczytać, spowoduje to wyświetlenie numeru wersji. Opiera się na ładowaniu, a nie na tym, co z nim robisz, prawda? – MCB

+0

niezupełnie, jeśli się go załaduje, numer wersji pozostanie taki sam, w przeciwnym razie pojawi się wiele aktualizacji, więc numer wersji zostanie pobity tylko przy aktualizacji (np. Update version = 2, gdzie wersja = 1) i jeśli żaden rekord nie pasuje gdzie otrzymasz błąd nieaktualnego obiektu. Problem z przeładowaniem strony może być taki, że jest on buforowany i nie przeładowujesz obiektu z DB. –

+0

Tak, przeglądarka używająca wersji z pamięci podręcznej jest czymś, co już znam – MCB