0

我正在创建一条记录,然后从 after create 过滤器中将新创建的记录的 id 推送到队列中。

从另一个脚本中,我正在从队列中读取 id 并立即读取 id 的 db 记录。

record = Model.find(id)# this is giving error: Couldn't find record with ID 8732

我正在使用带有 mysql2 gem 的 rails 2.3.14。

4

3 回答 3

1

你所经历的被称为竞争条件。

正如 ilan 指出的那样,您的第二个脚本或工作库正在尝试在记录完全写入(“提交”)之前访问它。

这个问题的一个常见解决方案是使用after_commit回调而不是 after_create / after_save 等。

Rails BestPractices 文章中的一个示例。

前:

class Notification < ActiveRecord::Base
  after_create :asyns_send_notification

  def async_send_notification
    NotificationWorker.async_send_notification({:notification_id => id})
  end
end

class NotificationWorker < Workling::Base
  def send_notification(params)
    notification = Notification.find(params[:notification_id])
    user = notification.user
    # send notification to user's friends by email
  end
end

使用 after_commit 生命周期钩子重构后:

class Notification < ActiveRecord::Base
  after_commit :asyns_send_notification, :on => :create

  def async_send_notification
    NotificationWorker.async_send_notification({:notification_id => id})
  end
end

进一步阅读:Rails API 文档中的 after_commit

于 2013-03-14T20:54:52.097 回答
0

也许查询结果"SELECT * FROM Model WHERE id=8732"在缓存中。

您应该尝试“重新加载”查询:

record = Model.find_by_id(id, true)
于 2013-03-14T14:57:38.807 回答
0

原因与事务隔离级别有关。尽管您可以读取刚刚插入的条目,但在提交事务之前另一个进程无法读取。此提交发生在控制器返回后。

于 2013-03-14T20:16:47.493 回答