2012-05-07 39 views
0

我有一個模型(PurchaseOrder - 縮寫PO)持有時間預算。用戶可以將小時記錄添加到此預算中,其中每個小時記錄可減少剩餘預算。Django 1.1信號 - 線程奇怪的時間問題

我實施了更新剩餘預算的信號。增加一小時記錄後,預算相應減少。由於計算可能非常耗時,因此我使用了一個線程來執行此任務。

def update_po_remaining_value(sender, instance, **kwargs): 
    CalculatePOThread(sender, instance).start() 
post_save.connect(update_po_remaining_value, sender=HourRecord)  
post_delete.connect(update_po_remaining_value, sender=HourRecord) 

線程CalculatePOThread通過獲取小時記錄集,並在扣除總小時記錄從預算

hr_set = HourRecord.objects.filter(purchase_order = po) 

在我dev.workspace這工作完全正常設置計算剩餘PO預算值。在生產post_save連接也工作正常,但我遇到post_delete信號一個奇怪的問題。經常發生的情況是,查詢HourRecord.objects.filter(purchase_order = po)返回的小時記錄總數仍包含已觸發CalculatePOThread線程的已刪除小時記錄。

無論如何,我在執行查詢之前,在線程中添加了6秒的延遲,從而避免了這種行爲。 time.sleep(6)。

有沒有人知道爲什麼會出現這種情況?看起來post_delete信號在記錄真正從數據庫中刪除之前被觸發..!?但是,這將是Django中的一個錯誤,這將是我最後的猜測。

回答

1

很難說,但我的猜測會是你遇到了線程安全問題。當你創建一個線程來處理一個長時間運行的任務時,你必須意識到,當它試圖完成時,一個類似的線程可以很容易地被解僱,並且負責相同的任務。通常,在使用線程時,您希望保持足跡最小化,換句話說,不要使它們高度依賴數據庫狀態等。

如果數據庫訪問必需的,在這種情況下,您需要設置鎖定以防止數據庫同時混淆。鑑於您正在運行Django 1.1,這將變得更加困難。如何在Django 1.1中實現表級鎖定將取決於您正在運行的數據庫服務器並保證自己的問題。

+0

感謝您的回答。一個額外的信息:我確信我是唯一一個在prod.env中搞亂的人。並且只是一個一個地觸發 - post.delete信號。因此,我確信沒有其他線程與我的測試衝突。因此,應該通過對象刪除命令設置鎖定,並且只應在釋放鎖定/刪除對象之後觸發post_delete信號。但我猜這是Django內部的東西,我無法影響。 PS:DB = postgres,webserver = apache。 –

+0

好像這個問題也在這裏討論:http://groups.google.com/group/django-haystack/browse_thread/thread/c452da9acfc04c64?pli=1 –