2013-09-25 64 views
0

我開始這名工人的10倍,給它的併發感:如何防止多名工人競相處理相同的任務?

class AnalyzerWorker 
    @queue = :analyzer 

    def self.perform 
    loop do 
     # My attempt to lock pictures from other worker instances that may 
     # try to analyze the same picture (race condition) 

     pic = Pic.where(locked: false).first 
     pic.update_attributes locked: true 

     pic.analyze 
    end 
    end 
end 

這段代碼實際上仍然是脆弱的競爭條件,我認爲原因之一是因爲有時間獲取解鎖之間的間隙圖片,並實際上鎖定它。

也許有更多的原因,任何強大的方法來防止這種情況?

回答

0

Active Record提供樂觀鎖定和悲觀鎖定。

爲了使用optimistic鎖定,該表需要有一個名爲lock_version類型整數的列 。每次更新記錄時,活動記錄都會增加lock_version列。如果更新請求 在lock_version字段中的值低於數據庫的lock_version列中當前的 ,則更新請求 將失敗並返回ActiveRecord :: StaleObjectError。

Pessimistic鎖定使用基礎數據庫提供的鎖定機制 。建立關係時使用鎖定,可以在選定的行上獲得排他鎖定 。使用鎖定的關係通常包含在事務中以防止死鎖情況的 。在引用鏈接提供

代碼樣本...

要麼應該工作,但每個人都需要不同的實現。從你在做什麼,我會考慮悲觀鎖定,因爲衝突的可能性相對較高。

但是,您目前的實施方式是兩種方式的混合,但正如您所指出的那樣,它確實不能解決問題。你可能能夠讓你的工作,但使用Active Record的實施是有道理的。

+0

有沒有進展?這有幫助嗎?還有什麼我可以做的? –

+0

這是否解決了您的問題?如果不是,你有問題嗎?如果是的話,你能接受嗎?謝謝... –

相關問題