簡體   English   中英

多個Django Celery Tasks嘗試保存到同一對象並失敗

[英]Multiple Django Celery Tasks are trying to save to the same object and failing

我的task.py文件中有三個Celery @tasks,它們通常由單獨的工作人員同時排隊和處理,每個工作時間相似。 我認為我遇到的問題是,他們都試圖在其他用戶配置文件完成之前更新同一用戶配置文件對象。 看來,完成的三個過程中的最后一個是成功寫入數據庫的過程。 如果我在兩次任務之間間隔幾秒鍾來運行它們,那么一切都很好。

任何想法是什么問題,或者是在嘗試實際保存之前一直嘗試保存到配置文件的方法是什么?

在此先感謝您的幫助!

我假設您使用的是django,因為您已對其進行了標記。 如果是這樣,則可以使用select_for_update( 文檔 )來鎖定對象。 這將阻止其他工作人員,直到交易完成。 如果您的任務運行時間較長,則可能會超時,因此請捕獲該異常並在必要時重試。

from django.db import transaction
from celery.task import task

@task
def mytask(mpk):
    with transaction.commit_on_success():
        my_obj = MyModel.objects.select_for_update().get(pk=mpk)
        ...

請注意,這不適用於sqlite。

Django ORM可以在這里發揮作用。 如果使用model_object.save()方法,它將更新所有字段。 如果您的任務要更新同一對象中的不同字段,則可以考慮使用ModelClass.objects.filter(pk=model_id).update(some_field=some_value) ,但是在這里您可能會陷入不同的RDBMS如何實現表/行鎖定的問題。

另一種選擇是使用Celery Chord並在完成所有提取用戶數據的任務后更新用戶配置文件。 您可能需要實現分布式信號量,因此唯一的和弦任務將同時針對同一用戶配置文件執行。

看起來更多是數據庫鎖定問題。 您是否嘗試過編輯配置文件並允許數據庫上的更多並發? 例如在Postgre Debian上編輯您的conf文件:

nano /etc/postgresql/9.4/main/postgresql.conf

然后,您可以在conf文件中設置以下內容:

max_connections=100
shared_buffers = 3000MB
temp_buffers = 800MB
effective_io_concurrency = 5
max_worker_processes = 15

這將使您可以在讀取時進行讀/寫操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM