为什么不锁!阻止其他人更新?



这是我的类:

class Plan < ActiveRecord::Base
  def testing
    self.with_lock do
      update_columns(lock: true)
      byebug
    end
  end
  def testing2
    self.lock!
    byebug
  end
end

我打开了两个导轨控制台。

在第一个控制台中:

p = Plan.create
=> (basically success)
p.id
=> 12
p.testing2
(byebug) # simulation of halting the execution,
(BYEBUG) # I just leave the rails console open and wait at here. I expect others won't be able to update p because I still got the lock.

在第二个控制台上:

p = Plan.find(12)
=> (basically said found)
p.name = 'should not be able to be stored in database'
=> "should not be able to be stored in database"
p.save!
=> true # what????? Why can it update my object? It's lock in the other console!

testing2 中的lock!不会锁定,而测试中的with_lock可以正常工作。谁能解释为什么lock!不起作用?

#lock!使用SELECT ...用于更新以获取锁。
根据PostgreSQL文档。

FOR UPDATE 会导致 SELECT 语句检索的行被锁定,就像进行更新一样。这可以防止它们被其他事务锁定、修改或删除,直到当前事务结束。

您需要一个事务来保持对某一行的锁定。

尝试
控制台1:

Plan.transaction{Plan.find(12).lock!; sleep 100.days}

控制台2:

p = Plan.find(12)
p.name = 'should not be able to be stored in database'
p.save 

#with_lock为您获取交易,因此您不需要显式交易。

(这是PostgreSQL文档。但我认为其他数据库也实现了类似的逻辑。 )

最新更新