我有这个应用程序,它在首次启动时会在我的服务器后端调用 2 个不同的 API 端点(两者的目的都非常不同)。然而,这两种方法都有一个 before_filter
,它使用 HTTP_AUTH
header (设备标识符 + api key )中传递的信息来验证调用。
如果它无法从我的设备表中找到具有提供的标识符的行,它会自动创建一个具有该标识符的新行。我的问题是,有时这 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
如果第二个 worker 试图插入一个带有已经存在的 udid 的设备,它将得到一个错误并且应该再次尝试搜索。
关于mysql - 2 个 HTTP 请求同时检查记录是否存在,如果不存在则创建它 = 重复记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12470538/