在我的 Rails 代码中,我需要确认仅当剩余的某条记录超过 1 条时才允许执行某项操作。出于这个原因,我需要锁定更新,然后执行读取。我的 Rails 代码如下所示:
PaymentProfile.transaction do
profiles = PaymentProfile.lock("LOCK IN SHARE MODE").where(user_id: xxx)
if profiles.count > 1
#allow
else
#do not allow
end
end
从理论上讲,这很有效,并且可以正确锁定行。但是,如果另一个请求遍历打开事务的相同代码路径,则会删除我在另一个进程中取出的锁,从而破坏了锁的目的。
来自 MySQL 文档:
Beginning a transaction also causes table locks acquired with LOCK TABLES to be released, as though you had executed UNLOCK TABLES. Beginning a transaction does not release a global read lock acquired with FLUSH TABLES WITH READ LOCK.