class State < ActiveRecord::Base
validates_uniqueness_of :identifier
end
现在假设有两个正在运行的进程可以同时插入其中两个记录。乘客就是一个很好的例子。这是一个人为的:
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?
我们的想法是,我们将时间值稍微改变一下。然后将整个东西复制/粘贴到两个不同的控制台中。
最终目标是让他们同时“释放”。怎么了?它们都成功创建了一个新的State对象,并且它们最后都返回false。
Soooo,我该如何阻止这种情况发生?
我使用MySQL的价值是什么,表格是InnoDB。
答案 0 :(得分:0)
除了正确的验证和数据库级别的唯一索引外,还使用#find_or_create辅助方法:
# 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")
这适用于任何适配器。