Rails:创建一个记录,然后立即阅读它

时间:2013-03-14 14:55:03

标签: mysql ruby-on-rails activerecord

我正在创建一条记录,然后从后创建过滤器中将新创建的记录的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。

3 个答案:

答案 0 :(得分:1)

您的经历被称为竞赛条件。

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

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

来自Article on 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

进一步阅读:after_commit in the Rails API docs

答案 1 :(得分:0)

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

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

record = Model.find_by_id(id, true)

答案 2 :(得分:0)

原因与事务隔离级别有关。虽然您可以读取刚刚插入的条目,但在提交事务之前不能再执行另一个进程。这个提交在控制器返回后发生。