Context: Product is getting updated by multiple threads. So it leads the race condition. So I am using optimistic locking because it is frequently not updated. For latest update state of the product is determined by updated_at
attribute.
For example, Prod (id=1) is updated at t1 on the machine:1. Same product(id=1) is updated at t2 on the machine:2. Now the state of Prod (id=1) on the machine:1 is stale.
Approach To determine stale: I will compare the value of updated_at
on the machine with the store value of updated_at
in the database value.
My main concern is setting the value of @original_updated_at
. Should I use attr_writer :original_updated_at
. Is this right way do optimistic locking.
attr_accessor : :original_updated_at
def original_updated_at
@original_updated_at || updated_at.to_f
end
def stale_object?
if updated_at.to_f > original_updated_at.to_f
@original_updated_at = nil
return true
else
@original_updated_at = updated_at.to_f
return false
end
end
def recalculate
tries = 0
begin
raise Product::StaleObjectError.new("StaleObjectError") if stale_object?
attributes["updated_at"] = Time.now.utc
Product.where(:id => self.id).update_all(attributes)
self.attributes = attributes
rescue Product::StaleObjectError => e
if tries < MAX_RETRIES
tries += 1
sleep(1 + tries)
reload
retry
else
raise Product::StaleObjectError("StaleObjectError")
end
end
end
Aucun commentaire:
Enregistrer un commentaire