2016-09-13 15 views
6

我想我已經消除了一切,但我不確定我是否完全理解OL。總的來說,假設你和我在一個團隊中保持最新的foo。我在一個房間裏,並決定節省時間,我會自己更新foo。所以我開始更新它。一分鐘後,你有相同的想法,並登錄編輯頁面以更新它。如果我先完成會怎樣?如果你先完成會發生什麼?如果配置失敗,它如何區分編輯人員和閱讀人員。如果我catch和重新加載更新鎖,我失去了我所有的更改,這是如何解決?在這裏,重做更新很簡單,但可能它是更復雜的表單對象的一部分。我的具體問題出現在我的瀏覽器中加載一個副本,後來忘了它,然後在我的控制檯(也鎖定: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.) 

事情我已經嘗試:

要看看另一個例子是裝載我在after_initialize回調添加puts "CALLED !!!!",但它只能打印一次。

從錯誤中搶救後檢查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 where version = 1),如果沒有記錄匹配那麼你會得到陳舊的對象錯誤。頁面重新加載的問題可能是它已被緩存,並且您沒有從數據庫重新加載對象。 –

+0

是的,使用緩存版本的瀏覽器是我已經熟悉的東西 – MCB