2010-08-26 190 views
1
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? 

这个想法是,我们改变时间值将在未来略有变化。然后复制/粘贴到两个不同的控制台。

最终目标是让他们在同一时间“释放”。怎么了?他们都成功创建了一个新的状态对象,并且最终都返回false。

Soooo,我该如何阻止这种情况发生?

为什么它值得我使用MySQL和表是InnoDB。

回答

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") 

,将与任何适配器配合使用。

+0

我想知道为什么这个答案被拒绝?它看起来很完整,并且确保没有任何事情能够通过数据库服务器的验证。 – 2011-04-13 16:42:53