Модель продукта Может обновляться несколькими пользователями.Однако одновременно только один пользователь должен иметь возможность обновляться.Для этого я хочу использовать оптимистическую блокировку для модели продукта с использованием updated_at.
Я реализовал следующий код для оптимистической блокировки.Существуют и другие способы реализации оптимистической блокировки, например, использование lock_version
.Однако из-за существующего ограничения кода я не могу реализовать использование lock_version
.
Product Model
MAX_RETRIES = 3
attr_writer :original_updated_at
def original_updated_at
@original_updated_at || updated_at
end
def stale_object?
if self.updated_at > original_updated_at
@original_updated_at = nil
return true
else
return false
end
end
def public_method
##code
result = nil
begin
result = private_method
self.original_updated_at = self.updated_at
rescue ActiveRecord::StaleObjectError => e
errors.add(:base, ": Following records are changed while you were editing.")
changes.except("updated_at").each do |name, values|
errors.add(name, values)
end
rescue Exception => error
##code
end
result
end
def private_method
tries = 0
begin
raise ActiveRecord::StaleObjectError.new(self, "Product is changed while you were editing") if stale_object?
attributes = #create hash using some code
#some code
attributes["updated_at"] = Time.now.utc
Product.where(:id => self.id).update_all(attributes)
self.original_updated_at = self.updated_at
rescue ActiveRecord::StaleObjectError => e
if tries < MAX_RETRIES
tries += 1
sleep(1 + tries)
self.reload
retry
else
raise ActiveRecord::StaleObjectError.new(self, "Product is changed while you were editing")
end
end
attributes
end