我正在創建一條記錄,然後從創建後的過濾器中將新創建的記錄的id推入隊列中。Rails:創建一條記錄,然後立即讀取問題
從另一個腳本中,我正在讀取隊列中的ID並立即讀取ID的db記錄。
record = Model.find(id)# this is giving error: Couldn't find record with ID 8732
我使用rails 2.3.14和mysql2 gem。
我正在創建一條記錄,然後從創建後的過濾器中將新創建的記錄的id推入隊列中。Rails:創建一條記錄,然後立即讀取問題
從另一個腳本中,我正在讀取隊列中的ID並立即讀取ID的db記錄。
record = Model.find(id)# this is giving error: Couldn't find record with ID 8732
我使用rails 2.3.14和mysql2 gem。
你所體驗的是一種競賽條件。
您的第二個腳本或工作者圖書館正在嘗試訪問該記錄,然後它已被完全書寫(「提交」),正如ilan指出的那樣。
一個常見的解決這個問題,使用after_create/after_save的等
從Article on Rails BestPractices一個例子的after_commit回調來代替。
前:
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
也許查詢結果"SELECT * FROM Model WHERE id=8732"
在高速緩存上。
你應該嘗試「刷新」查詢:
record = Model.find_by_id(id, true)
原因與事務隔離級別做。儘管您可以讀取剛纔插入的條目,但在事務提交之前,另一個流程不能進行。此提交發生在控制器返回後。
謝謝! after_commit回調默認情況下在rails 2中不可用,所以您需要使用gem。我使用的解決方案是在對新創建的記錄進行讀取查詢之前的一段時間內使用「睡眠」。 – Akarsh 2013-03-15 08:26:45