2013-09-06 4 views
2

작업 시간이 비슷한 별도의 작업자가 대기열에 넣고 동시에 처리하는 세 개의 Celery @task가 task.py 파일에 있습니다. 내가 실행중인 것으로 생각되는 문제는 다른 사용자가 완료되기 전에 모두 동일한 사용자 프로필 개체를 업데이트하려고한다는 것입니다. 완료 할 세 프로세스 중 마지막 프로세스는 데이터베이스에 성공적으로 기록하는 프로세스입니다. 작업을 몇 초간 실행하면 작업이 모두 정상적으로 완료됩니다.여러 Django Celery 작업이 같은 개체에 저장하려고하지만 실패했습니다

어떤 문제인지 또는 실제로 작동 할 때까지 프로필에 저장하려고 시도하는 방법은 무엇입니까?

미리 도움 주셔서 감사합니다.

+0

이들이 각 프로세스에서 업데이트되는 별도의 필드 일지라도? 동일한 userprofile 행을 사용하여 작업을 동 기적으로 문자열로 묶는 방법이 있습니까? – bevinlorenzo

+0

시도 할 수있는 방법이 있습니까 : 제외 : 프로필 저장 논리? – bevinlorenzo

+0

Wikipedia에 대해 더 알고 싶다면 ACID https://en.wikipedia.org/wiki/ACID와 Isolation에 대한 기사를 참고하십시오 : https://en.wikipedia.org/wiki/Isolation_%28database_systems%29 – zero323

답변

2

장고 ORM이 트릭을 할 수 있습니다. model_object.save() 메서드를 사용하면 모든 필드가 업데이트됩니다. 작업이 동일한 객체의 다른 필드를 업데이트하는 경우 ModelClass.objects.filter(pk=model_id).update(some_field=some_value)을 사용하는 것을 고려할 수 있지만 여기에서는 서로 다른 RDBMS가 테이블/행 잠금을 구현하는 방법이 다를 수 있습니다.

또 다른 옵션은 Celery Chord을 사용하고 사용자 데이터를 가져 오는 모든 작업이 완료되면 사용자 프로필을 업데이트하는 것입니다. 분산 된 세마포어 (semaphore)를 구현해야 할 수도 있으므로 코드 작업 만이 동일한 사용자 프로필에 대해 동시에 실행됩니다.

3

장고를 사용하고 있다고 가정하기 때문에 장고를 사용한다고 가정합니다. 그렇다면 select_for_update (documentation)를 사용하여 개체를 잠글 수 있습니다. 그러면 트랜잭션이 완료 될 때까지 다른 작업자가 차단됩니다. 작업이 오랜 시간 실행되면 시간 초과가 발생할 수 있으므로 해당 예외를 잡아 필요한 경우 다시 시도하십시오.

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에서는 작동하지 않습니다.

0

더 많은 데이터베이스 잠금 문제가있는 것 같습니다. 구성 파일을 편집하고 데이터베이스에 더 많은 동시 통화를 허용하려고 시도 했습니까? Postgre 데비안에 인스턴스가 귀하의 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 

이 당신이 discribing하는대로 읽기/쓰기 할 수 있도록해야한다.

관련 문제