2012-05-07 2 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이 완벽하게 잘 작동 내 dev.workspace에서 예산

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

에서 설정 한 총 시간 기록을 시간의 레코드 집합을 얻고 공제를 통해 나머지 PO 예산 값을 계산한다. 프로덕션에서는 post_save 연결도 제대로 작동하지만 post_delete 신호와 관련된 이상한 문제가 발생합니다. HourRecord.objects.filter (purchase_order = po) 쿼리에 의해 반환 된 시간 레코드의 합계에는 여전히 CalculatePOThread 스레드를 트리거 한 삭제 된 시간 레코드가 포함되어 있습니다.

아무튼 나는 쿼리를 실행하기 전에 스레드에 6 초의 지연을 추가하는 동작을 피했습니다. time.sleep (6).

아무도 이러한 상황이 발생할 수있는 이유가 있습니까? 레코드가 실제로 데이터베이스에서 삭제되기 전에 post_delete 신호가 트리거 된 것 같습니다.!? 하지만 이것은 장고의 버그 일 것이고 이것은 나의 마지막 추측 일 것입니다.

답변

1

말하기 어렵지만 제 생각에 스레드 안전 문제가 발생했을 것입니다. 장기 실행 작업을 처리하기 위해 스레드를 생성 할 때 완료하려고 시도하는 동안 유사한 스레드가 동일한 스레드로 쉽게 해제 될 수 있음을 알아야합니다. 일반적으로 스레드로 작업 할 때, 사용자 공간을 최소화하거나 다른 말로하면 데이터베이스 상태 등에 크게 의존하지 않기를 원합니다.

데이터베이스 액세스 이 필요하면이 필요하며이 경우에는 데이터베이스가 동시에 엉망이되지 않도록 잠금 장치를 설정해야합니다. 당신이 Django 1.1을 돌리고 있다면, 이것은 훨씬 더 어려울 것입니다. Django 1.1에서 테이블 레벨 잠금을 수행하는 방법은 실행중인 데이터베이스 서버에 따라 달라지며 자체 질문을해야합니다.

+0

답변 해 주셔서 감사합니다. 추가 정보 한 가지 : 나는 prod.env에서 주변을 뒤적 거리는 유일한 사람이라고 확신했습니다. 하나씩 post.delete 신호를 유발했다. 따라서 다른 스레드가 내 테스트와 충돌하지 않는다고 확신했습니다. 따라서 잠금은 object delete 명령에 의해 설정되어야하며 post_delete 신호는 잠금이 해제 된 후/객체가 삭제 된 후에 만 ​​트리거되어야합니다. 하지만 영향을 줄 수없는 장고 내부 자료입니다. 추신 : DB = postgres, webserver = apache. –

+0

이 이슈로 보입니다. http://groups.google.com/group/django-haystack/browse_thread/thread/c452da9acfc04c64?pli=1 –