2016-06-28 15 views
1

我有一個Sidekiq作業,是在after_save中開始,它看起來好像它獲取了錯誤的數據,我很好奇如果這是我應該期待的行爲。這項工作的目標基本上是構建對象的緩存版本。Rails after_save回調,提交是否完成,更改可以訪問一個Sidekiq作業

我有一個項目可以將is_enabled設置爲true/false。

在after_save的,我有:

after_save 
    ItemWorker.peform_async 
end 

,並在我的員工,我有:

def perform item_id 
    mi=Item.find(item_id) 
    Queryable.manage_object mi # <-- will build our cached objects here 
    end 

在我after_save的開始,應該我所有的變化是已在數據庫中,承諾 - 有什麼辦法Postgres可以在這一點上鎖定行(我在Postgres 9.4)?

有沒有辦法讓我檢查它是否已保存,或者我應該將其移至after_commit(或其他地方)?

回答

1

在將新/更改的數據提交給數據庫之前,Sidekiq很有可能會運行該工作者,這意味着該工作人員將看到錯誤的數據。

正如Sidekiq FAQ解釋,最好的做法是使用after_commit

Sidekiq試圖交易實際上已經承諾之前執行你的工作。使用Rails的after_commit :on => :create鉤子或將作業創建移到事務塊的外部。

+0

thx張貼到這 - 有道理(有點),我認爲這是發生了什麼,但似乎有點反直覺。我的理解是after_save將會在你的主對象被保存並且after_commit被保存在輔助對象之後(比如你在代碼中強制執行一個事務)。我的意思是它被稱爲after_save。 – timpone

+0

這有點令人困惑,但的確如此ActiveRecord的工作原理:在'after_save'期間更改已被「保存」,但尚未提交到數據庫。在單個線程的請求/響應場景中,區別並不重要,但由於Sidekiq在單獨的進程中運行,因此確切的事務邊界非常重要。 –

+0

hmm ....但是如果我在after_save的末尾選出一個相同項目的新副本,它確實給了我正確的值。我相信你是對的,它與這個交易界限有關,但想知道更多。有什麼地方可以指點我嗎?在兩種情況下(單一流程模型和後臺模式),我們都要進入數據庫並選擇記錄。 sidekiq工作有些人認爲它是一個開放的事務,然後訪問先前的數據,其中單個請求/ resposne將事務視爲已提交? – timpone

相關問題