验证中的ActiveRecord竞争条件

时间:2014-02-21 16:52:20

标签: ruby-on-rails activerecord concurrency

我想澄清一些关于ActiveRecord的内容。说我有这样的场景:

class Purchase < ActiveRecord::Base
  belongs_to :song
end

class Song < ActiveRecord::Base
  has_many :purchases
  validate :cannot_update_if_being_sold

  def cannot_update_if_being_sold
    errors.add(:song, "Cannot update beats while beat is being sold.") if !self.purchases.empty?
  end
end

现在假设我有一个现有的Song实例,我尝试更新它。这里没有竞争条件吗?具体做法是:

  1. 运行歌曲验证,一切都通过
  2. 创建歌曲购买并保存到db
  3. 将歌曲保存到db
  4. 如何防止这种情况发生?我不确定如何在这种情况下使用锁,因为购买是一个has_many。

    谢谢!

1 个答案:

答案 0 :(得分:0)

购买会影响购买模式,歌曲的更新会影响歌曲模型 由于ActiveRecord将这些模型映射到数据库中的单独表,因此单独访问它们不会涉及“竞争条件”。

但是,我看你是否要删除一首歌,任何正在进行的购买都会引发错误。 定位该场景而不是UPDATE场景。

此外,但这应该是标准的,不要更新歌曲的主键。