防止多个活动记录进程插入重复记录 类状态00,:sec=>15) 睡眠0.001 结束 ActiveRecord::Base.transaction do s=State.new;s、 identifier=“UNIQ” s、 救命! 结束 s、 有效吗?

防止多个活动记录进程插入重复记录 类状态00,:sec=>15) 睡眠0.001 结束 ActiveRecord::Base.transaction do s=State.new;s、 identifier=“UNIQ” s、 救命! 结束 s、 有效吗?,activerecord,Activerecord,现在假设有两个正在运行的进程可以同时插入其中两个记录。乘客就是一个很好的例子。这里有一个人为的例子: class State < ActiveRecord::Base validates_uniqueness_of :identifier end 状态。按标识符(“UNIQ”)查找。删除rescue nil 而Time.now17,:min=>00,:sec=>15) 睡眠0.001 结束 ActiveRecord::Base.transaction do s=State.new;s

现在假设有两个正在运行的进程可以同时插入其中两个记录。乘客就是一个很好的例子。这里有一个人为的例子:

class State < ActiveRecord::Base
  validates_uniqueness_of :identifier
end
状态。按标识符(“UNIQ”)查找。删除rescue nil
而Time.now17,:min=>00,:sec=>15)
睡眠0.001
结束
ActiveRecord::Base.transaction do
s=State.new;s、 identifier=“UNIQ”
s、 救命!
结束
s、 有效吗?
我们的想法是,我们将时间值更改为在将来稍微更改。然后将整个内容复制/粘贴到两个不同的控制台中

最终目标是让他们同时“释放”。会发生什么?它们都成功地创建了一个新的状态对象,最后都返回false

Soooo,我怎样才能阻止这一切发生

值得一提的是,我使用的是MySQL,表是InnoDB。

除了正确的验证和数据库级别的唯一索引外,您还可以使用#find_或_createhelper方法:

State.find_by_identifier("UNIQ").delete rescue nil
while Time.now < Time.now.change(:hour => 17, :min => 00, :sec => 15)
  sleep 0.001
end
ActiveRecord::Base.transaction do
  s = State.new;s.identifier = "UNIQ"
  s.save!
end
s.valid?
迁移中的
#
添加索引:states,:identifier,:unique=>true
类状态

这适用于任何适配器。

我想知道为什么这个答案被否决了?它看起来是完整的,并确保任何东西都不会通过数据库服务器的验证。
# In a migration
add_index :states, :identifier, :unique => true

class State < ActiveRecord::Base
  validates_uniqueness_of :identifier
end

State.find_or_create_by_identifier("UNIQ")