我有这个应用程序,在第一次启动时,在我的服务器后端调用 2 个不同的 API 端点(两者都具有非常不同的目的)。但是,这两种方法都有一个before_filter
,该使用HTTP_AUTH
标头中传递的信息(设备标识符 + api 密钥)对调用进行身份验证。
如果它无法从我的设备表中找到具有提供的标识符的行,它会自动使用该标识符创建一个新行。我的问题是,似乎有时 2 个调用是如此同时,以至于两个请求都找不到任何记录,因此它们都创建了一个新的设备行(导致具有相同设备标识符的重复行)。
我的身份验证方法如下所示:
def current_user
authenticate_with_http_basic do |udid, secret|
if secret == APP_SECRET
@device = Device.find_by_udid(udid)
if !@device
@device = Device.new
@device.udid = udid
@device.created_on = DateTime.now.utc
end
// set a bunch of properties on @device
@device.connected_at = DateTime.now.utc
@device.save
end
end
end
这就是发明唯一索引的原因。在udid
上放置一个唯一的索引(这样每个 udid 只能存在一个设备),然后你的代码可能看起来像这样(伪代码):
def process
device = Device.find
unless device
device = Device.create
end
# do your work with the device
rescue ActiveRecord::RecordNotUnique
retry # this is an actual ruby keyword. It means "run this begin..end block
# again". In this case, there's an implicit begin..end block, which is
# the method body.
end
如果第二个工作线程尝试插入已存在的带有 udid 的设备,它将收到错误,应再次尝试搜索。