2016-09-13 5 views
6

Я думаю, что я все устранил, но я не уверен, что понимаю OL достаточно точно, чтобы быть уверенным. В общем, допустим, вы и я в команде, чтобы обновить foo. Я в одной комнате и решил сэкономить время, я сам обновлю себя. Поэтому я начинаю его обновлять. Через минуту у вас будет такая же идея и войдите на страницу редактирования, чтобы обновить ее. Что произойдет, если я закончу сначала? Что произойдет, если вы закончите сначала? В конфигурации, где он терпит неудачу, как он отличает кого-то от редактирования и чтения. Если я catch и перезаряжаю, чтобы обновить блокировку, я теряю все свои изменения, как это решить? Здесь просто обновить обновление, но потенциально это часть более сложного объекта формы.Получение ошибки объекта Stale. Оптимистичное блокирование: как это работает?

Моя конкретная проблема возникла, когда (лучше всего я могу разобрать) загрузил одну копию в мой браузер, позже забыл об этом, а затем один в моей консоли (также заблокирован: 0?) Не смог обновить тот, что был на моей консоли, ошибка устаревших объектов. Заметили браузер. Закрыл мою консоль. Пытался перезагрузить мой браузер и получил также устаревшую ошибку объекта. Вот код, который терпит неудачу:

=> 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.) 

Вещи, которые я пробовал:

Чтобы увидеть, если другой экземпляр был загружен я добавил puts "CALLED !!!!" в after_initialize обратного вызова, но это только отпечатанные один раз.

И проверка self.changed после спасения от ошибки и получить обратно ["updated_at", "failed_view_attempts", "failed_view_at"]

ответ

1

нужно установить lock_version столбца по умолчанию к нулю (0).

0

Оптимистическая блокировка основана на номере версии объекта.

Чтение и объект не должны влиять на номер версии вообще.

Если вы пытаетесь обновить какой-либо объект, сравнивается этот номер версии (в sql фактически оператор обновления используется, например, «update ... where version = 1 and ...») и увеличивается при обновлении.

Если при попытке обновления не удается выполнить сравнение, вы получите ошибку устаревшего объекта. Это означает, что объект был изменен кем-то еще, когда вы делали свои изменения.

Для устранения этой ошибки необходимо загрузить объект повторно, чтобы получить актуальную версию и, возможно, сменить изменения вручную (предоставив пользователю некоторую информацию об этом, и пусть пользователь может решить, например).

+0

Но если я редактирую, кто-то вызывает экземпляр той же строки, чтобы прочитать его, он будет бить номер версии. Он основан на загрузке, а не на том, что вы с ним делаете, правильно? – MCB

+0

На самом деле, если вы его загрузите, номер версии останется прежним, в противном случае будет много обновлений, поэтому номер версии будет загружен только при обновлении (то есть: update version = 2, где version = 1), и если запись не соответствует где тогда вы получите ошибку устаревшего объекта. Проблема с перезагрузкой страницы может заключаться в том, что она кэширована, и вы не перезагружаете объект из БД. –

+0

Да, браузер с использованием кешированной версии - это то, что я уже знаком с – MCB