2013-03-14 3 views
0

나는 레코드를 생성하고 큐에 새로 생성 된 레코드의 ID를 after create 필터에서 푸시한다.레일 : A 레코드를 생성하고 즉시 읽는다.

다른 스크립트에서 큐에서 ID를 읽고 ID의 DB 레코드를 즉시 읽는 중입니다.

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

나는 mysql2 보석과 함께 레일 2.3.14를 사용하고 있습니다.

답변

1

당신이 경험 한 것은 경쟁 조건으로 알려져 있습니다.

두 번째 스크립트 또는 작업자 라이브러리가 완전히 기록되기 전에 ("커밋 됨") ilan이 지적한대로이 레코드에 액세스하려고합니다.

이 문제에 대한 일반적인 해결책은/after_save 등

Article on Rails BestPractices에서 예 after_create 대신 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 

추가 읽기 : after_commit in the Rails API docs.

+0

감사합니다. 레일 2에서는 기본적으로 after_commit 콜백을 사용할 수 없으므로 젬을 사용해야합니다. 필자가 사용하는 솔루션은 새로 생성 된 레코드에 대한 읽기 쿼리를 만들기 전에 '잠자기'를 사용하는 것입니다. – Akarsh

0

쿼리 결과 "SELECT * FROM Model WHERE id=8732"이 캐시에있을 수 있습니다.

쿼리를 "다시"를 시도해야

:

record = Model.find_by_id(id, true) 
0

이유는 트랜잭션 격리 수준과 관련이있다. 방금 삽입 한 항목을 읽을 수는 있지만 트랜잭션이 커밋 될 때까지 다른 프로세스를 사용할 수 없습니다. 이 커밋은 컨트롤러가 반환 된 후에 발생합니다.

관련 문제