mysql - 2 个 HTTP 请求同时检查记录是否存在,如果不存在则创建它 = 重复记录

标签 mysql ruby-on-rails ruby

我有这个应用程序,它在首次启动时会在我的服务器后端调用 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/

相关文章:

mysql - 从同一表的其他列更新 mysql 列字段值

mysql - 被杀死的进程仍在我的进程列表中

php - MySQL 中的理解断开连接

javascript - Rails webpack js和ajax刷新

ruby-on-rails - Ruby/Rails是否具有++等效项?

java - 这是 websocket 编程的正确使用吗?

ruby - STDOUT.sync = true 是什么意思?

ruby - rvm 中每个 ruby​​ 版本的不同 ruby​​gem 版本

mysql - 从列范围内的表中获取结果集?

ruby - Ubuntu rake 中止! NameError:未初始化的常量 ActionDispatch::XmlParamsParser