2013-10-15 54 views
1

我似乎已經在我的Rails應用程序中的競爭條件。在刪除用戶以及依賴它的所有相關模型時,有時會由用戶創建新的關聯模型。如果我們刪除大量內容,用戶刪除操作可能需要一段時間,因此這裏存在競爭條件是有意義的。這最終會創建指向不存在的用戶的模型。競爭條件銷燬回調

我試圖通過創建UserDeletion模型,它作爲一種互斥鎖的解決這個。在開始刪除用戶之前,它會創建一個新的UserDeletion記錄。當用戶嘗試創建新內容時,它會檢查以確保關聯的UserDeletion記錄不存在。完成後,它將刪除它。

這並沒有解決這個問題,雖然,所以我不知道其他人是如何處理類似的問題與AR回調和比賽條件。

回答

-1

首先,當有大量內容關聯時,我們繼續使用SQL DELETE而不是關閉Rails destroy來手動刪除進程。 (雖然這可能並不適合你,如果你不小心推出了很多回調的依賴,做一些記錄被破壞後)

def custom_delete 
    self.class.transaction do 
    related_objects.delete_all 
    related_objects_2.delete_all 
    delete 
    end 
end 

如果你發現自己寫這一切的時候,你可以簡單地把它包裝內部類方法,接受要刪除的related_objects鍵的列表。

class ActiveRecord::Base 
    class << self 
    def bulk_delete_related(*args) 
     define_method "custom_delete" do 
     ActiveRecord::Base.transaction do 
      args.each do |field| 
      send(field).delete_all 
      end 
     end 

     delete 
     end 
    end 
    end 
end 


class SomeModel < ActiverRecord::Base 
    bulk_delete :related_objects, :related_objects2, :related_object 
end 

我直接在ActiveRecord :: Base類中插入類方法,但可能你應該更好地將它提取到模塊。此外,這隻會加快速度,但不能解決原來的問題。

其次,你可以介紹FK約束(我們這樣做是爲了保證完整性,我們做了很多自定義的SQL)。只要有鏈接的對象,它將以用戶不會被刪除的方式工作。雖然它可能不是你想要的。爲了提高此解決方案的有效性您可以隨時將用戶刪除委託給後臺作業,該操作將重試刪除用戶,直至其實際可以刪除(沒有新對象放入)

或者您也可以像我們一樣在某些情況下,我以前的工作。如果刪除用戶更重要,而不是確保沒有殭屍記錄,請使用一些刷卡過程來清理時間。

最後的真相是在中間某個地方 - 應用約束到確實需要刪除用戶之前進行清理,僅僅依靠掃地機刪除不應刪除用戶干擾不太重要的關係。

問題是不平凡的,但它應是可解到一定程度。