在我的用户模型中,我有:
validates_uniqueness_of:fb_uid(我正在使用facebook连接)。
然而,有时候,我在用户注册时会收到重复的行。这非常糟糕。
两条记录的创建时间在100毫秒之内。我无法确定它是否发生在两个单独的请求中(heroku日志记录糟透了,只返回到目前为止,它只发生了两次)。
两件事:
我无法在开发中复制。
任何想法都会非常感激。
登录功能
def self.create_from_cookie(fb_cookie, remote_ip = nil)
return nil unless fb_cookie
return nil unless fb_hash = authenticate_cookie(fb_cookie)
uid = fb_hash["uid"].join.to_i
#Make user and set data
fb_user = FacebookUser.new
fb_user.fb_uid = uid
fb_user.fb_authorized = true
fb_user.email_confirmed = true
fb_user.creation_ip = remote_ip
fb_name_data, fb_friends_data, fb_photo_data, fb_photo_ext = fb_user.query_data(fb_hash)
return nil unless fb_name_data
fb_user.set_name(fb_name_data)
fb_user.set_photo(fb_photo_data, fb_photo_ext)
#Save user and friends to the db
return nil unless fb_user.save
fb_user.set_friends(fb_friends_data)
return fb_user
end
答案 0 :(得分:1)
我对facebook connect非常熟悉,但如果两个独立用户中的两个独立用户在请求完成之前连续快速地发出请求,是否可以获得两个相同的uuid? (否则称为竞争条件)validates_uniqueness_of仍然可能受到这种竞争条件的影响,详情可以在这里找到:
http://apidock.com/rails/ActiveModel/Validations/ClassMethods/validates_uniqueness_of
因为执行了此检查 在数据库之外还有一个 重复值的可能性 插入两个并行事务。 为了保证不这样做你应该 在该字段上创建唯一索引。 有关详细信息,请参阅add_index。
您可以确实确保通过添加数据库约束永远不会发生这种情况。将其添加到数据库迁移中,然后运行它:
add_index :user, :fb_uid, :unique => true
现在用户会收到错误而不是能够完成请求,这通常比在数据库中生成非法数据更好,您必须手动调试和清理。
答案 1 :(得分:0)
来自Ruby on Rails v3.0.5模块ActiveRecord :: Validations :: ClassMethods http://s831.us/dK6mFQ
并发性和完整性
使用此[validates_uniqueness_of] 验证方法与 ActiveRecord :: Base#save不会 保证没有重复 记录插入,因为唯一性 检查应用程序级别 本质上容易出现竞争条件。 例如,假设有两个用户 尝试发表评论 时间,评论的标题必须是 独特。在数据库级, 这些用户执行的操作可以 在下面交错 方式:......
答案 2 :(得分:0)
您的代码中似乎存在某种竞争条件。要检查这一点,我将首先更改代码,以便首先提取facebook值,然后我将创建一个新的facebook对象。
然后我强烈建议您编写一个测试来检查您的函数是否被执行一次。似乎它被执行了两次。
在此之后,等待获得Facebook结果似乎存在竞争条件。