跳到內文 跳到搜尋

什麼是樂觀鎖定

Optimistic 鎖定讓多個使用者可以同時取得同筆記錄進行編輯,且預設資料會產生最少的衝突。當另一個程序在開啟記錄後對記錄進行更動,此方法會檢查這個更動,如果發生這種情況,系統會擲回 ActiveRecord::StaleObjectError 例外,並略過更新。

請參考 ActiveRecord::Locking::Pessimistic 以取得替代方案。

用法

如果存在 lock_version 欄位,Active Record 會支援樂觀鎖定。每次更新記錄都會遞增整數欄位 lock_version,而鎖定機能會確保重複實例化的記錄,會讓最後一次儲存的記錄引發 StaleObjectError 例外,假設第一筆記錄也已更新。範例

p1 = Person.find(1)
p2 = Person.find(1)

p1.first_name = "Michael"
p1.save

p2.first_name = "should fail"
p2.save # Raises an ActiveRecord::StaleObjectError

Optimistic 鎖定也會在物件銷毀時檢查舊資料。範例

p1 = Person.find(1)
p2 = Person.find(1)

p1.first_name = "Michael"
p1.save

p2.destroy # Raises an ActiveRecord::StaleObjectError

接著,您負責處理衝突,方法是擷取例外,然後執行回滾、合併或套用其他適用商業邏輯來解決衝突。

此鎖定機制會在單一 Ruby 程序中運作。若要讓所有網路要求都能正常運作,建議方法是將 lock_version 新增為表單中的隱藏欄位。

此動作可以透過設定 ActiveRecord::Base.lock_optimistically = false 來關閉。若要覆寫 lock_version 欄位名稱,請設定 locking_column 類別屬性

class Person < ActiveRecord::Base
  self.locking_column = :lock_person
end
命名空間