On 11/2/10 4:17 PM, Marnen Laibow-Koser wrote:
> 
> I think you do.  If I remember correctly, :lock doesn't do any actual 
> DB-level locking -- it just sets a lock field that ActiveRecord expects. 
> Transactions, OTOH, *do* do DB-level locking, but shouldn't introduce 
> read locks for the sort of operations you're doing.  And you're not 
> doing any DB writes here.
> 

:lock is supposed to do row-level locking via the DB facilities:

http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html

I believe it's the optimistic locking that uses the lock field in active
record, and throws a StaleObjectException if things have been modified.

Anyway, we discovered what the problem was.  So for the sake of the
archives...

:lock won't block on a standard SELECT.  Only SELECT FOR UPDATE.

So if I run this code in terminal one:

Foo.transaction do
  f = Foo.find(1, :lock => true)
  1.upto(10000000) { |i| puts i }
end

And this in terminal two while terminal one is spitting out numbers:

Foo.transaction do
  puts Foo.find(1, :lock => true).inspect
end

The second process will block, even for that read-only operation, until
the transaction in the first process ends.

-- 
Grant

"I am gravely disappointed. Again you have made me unleash my dogs of war."

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to