ruby-on-rails - 由 find_or_create_by_ 创建的重复记录

标签 ruby-on-rails ruby-on-rails-3 activerecord

我有一个 ActiveRecord 对象 Corporation,在我的项目中创建该对象实例的唯一调用如下所示:

corp = Corporation.find_or_create_by_eveid_and_user_id(self.corporation_eveid, self.account.user_id)

然而不知何故,在我的应用程序愉快地运行了几天之后,出现了重复的记录——记录了 eveid 和 user_id 具有相同值的地方。这怎么可能?我更新这些记录的方式是否有可能导致此问题的错误?

我最终为表添加了一个唯一的复合索引。这应该可以解决问题,但我不明白它是如何发生的。

这是 Rails 3.0.7。

最佳答案

find_or_create 不执行任何锁定,也不尝试防止竞争条件。这只是一种方便的方法。如果竞争条件成为问题,您将需要:

  1. 如果您发现其他人在您之前写过,请使用事务并回滚
  2. (如果你真的期待竞争条件更好),执行悲观锁定。这是您首先从表中获取排他锁的 SELECT,然后执行写入并清除锁的地方。在 MySQL InnoDB 表中,这是 SELECT ... FOR UPDATE。如果您没有要锁定的引用点(即没有外键或数据库中已存在的任何内容),那么您将不得不坚持使用 (1)。

编辑 |如果您可以在架构级别添加 UNIQUE 约束,如果这是一个真正的完整性问题,我建议您也这样做。

关于ruby-on-rails - 由 find_or_create_by_ 创建的重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6163125/

相关文章:

ruby-on-rails-3 - Rails 3 删除数组的所有元素

ruby-on-rails - 获取接收类方法调用的 ActiveRecord_Relation

ruby - ActiveRecord,通过多态属性查找

ruby-on-rails - Rails 3 DISTINCT QUERY

ruby - 使用 Her、Faraday 在 API 中进行 Rails 分页

ruby-on-rails - ActiveRecord - 查询多态关联

ruby-on-rails - 使用 RSpc 2.9.0 + FactoryGirl 3.2 通过验证测试 has_many

ruby-on-rails - rails 3 : Rendering certain attributes of an array of objects in JSON

ruby-on-rails - Sidekiq与单队列并发

ruby-on-rails - 选择在数组属性中包含值的 Rails 对象