I've been reading about locking for ActiveRecord, but it seems a
little vague to me. My situation is this: I have a controller that
assigns jobs to people who are logged in. The basic code is:
j = Job.find :first, :conditions => 'employee_id is null'
unless j.nil?
j.employee = current_employee
j.save
end
Of course, this can cause, and has caused a race condition. My
temporary fix was to add :order => 'RAND()', so that the possibility
of a collision is reduced, but the possibility is still there.
It seems the lock! might fix this, but I don't understand what really
happens here. If I lock! the record, what happens to the second
employee that tries to pull the record and save it?
Is there another method I should be looking at?
Of course, this can cause, and has caused a race condition. My
temporary fix was to add :order => 'RAND()', so that the possibility
of a collision is reduced, but the possibility is still there.
It seems the lock! might fix this, but I don't understand what really
happens here. If I lock! the record, what happens to the second
employee that tries to pull the record and save it?
lock! is a database level lock (ie select ... for update). You get an
exclusive lock on that row that lasts for the duration of the current
transaction (corollary: if you do this outside a transaction it
basically does nothing). If something else tries to read or update
that row that attempt will block until the lock is released (or the
thing waiting for the lock gets bored of waiting)
Is there another method I should be looking at?
Rails' optimistic locking may also be relevant
Fred