mysql - Rails + MySQL + Transactions + Locking,如何防止打开事务解锁表?

标签 mysql ruby-on-rails transactions locking innodb

在我的 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.

最佳答案

我假设另一个请求将由另一个进程处理,或者至少由另一个连接(到 MySQL)处理(抱歉,我对 Ruby-on-rails 一无所知)。

一个给定事务获取的锁不能被另一个事务释放。这就是锁的真正目的。作为the manual说:

UNLOCK TABLES explicitly releases any table locks held by the current session

如果我的假设是正确的,就没有什么可担心的。否则,如果两个请求可能同时使用同一个连接,那么这个架构就有些可疑了……

关于mysql - Rails + MySQL + Transactions + Locking,如何防止打开事务解锁表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17002791/

相关文章:

ruby-on-rails - 有没有办法根据地理编码位置获取时区的 UTC 偏移量?

django - 是否可以在 Celery 任务中运行 VACUUM 命令?

SELECT 中的 Mysql 死锁.. 如果不存在 INSERT

html - 无法让 <span> 标签在超链接内工作

ruby-on-rails - Rails-Thin 服务器在生产(实时)模式下停止。网站关闭

ruby-on-rails - column_types 在 Rails 4.0.1 中为 nil

transactions - 在谈论数据库系统时,什么构成事务层?

mysql - 函数 MySQL 不存在

mysql - 如果有图像sql,则让用户具有用户的第一张图像

c# - 如何使用C#查询MYSQL数据并显示?