Stale object errors

I’m running into a couple of stale object problems with methods that
at first glance appear fairly atomic - eg Message.update(params[:id],
{:body => params[:value]})
Of course, Rails has to instantiate the object & validate it before
it updates the database, so it’s not actually atomic, hence the
occasional staleobject error.

So I’ve been wondering about creating a block method looking
something like:

def update_volatile_object
num_attempts = 5
while num_attempts>0
begin
yield # the block should do something along the lines of
Message.update(blah)
break # If we got here, we didn’t raise a stale object error
rescue ActiveRecord::StaleObjectError => e
num_attempts -= 1
end
end

raise DatabaseSeemsTooDamnBusy if num_attempts==0
end

…but it feels like I’m missing something - does Rails supply any
functionality to do this for me? Any suggestions on how to improve
the above?

On 8/16/06, Jonathan del Strother [email protected] wrote:

end

raise DatabaseSeemsTooDamnBusy if num_attempts==0
end

You shouldn’t be locking the table at all if you find yourself bending
over
backward to circumvent the lock.

If you’re working with frequently stale records, consider using
pessimistic
locking instead (or rethinking the behavior that requires locking at
all).

def next!
transaction do
task = find(:first, :conditions => [‘claimed=?’, false], :lock =>
true)
task.claimed = true
task.save!
task
end
end

jeremy