2010-05-26 4 views
2

lightcd를 통해 lighttpd에서 실행되는 django 응용 프로그램이 있습니다. FCGI 실행 스크립트는 다음과 같습니다.django 다중 프로세스 문제

python manage.py runfcgi socket=<path>/main.socket 
    method=prefork \                          
    pidfile=<path>/server.pid \                                   
    minspare=5 maxspare=10 maxchildren=10 maxrequests=500 \ 

저는 SQLite를 사용합니다. 그래서 나는 동일한 DB와 함께 작동하는 10 가지 프로세스를 가지고 있습니다. 다음으로 2 전망이 있습니다

def view1(request) 
    ... 
    obj = MyModel.objects.get_or_create(id=1) 
    obj.param1 = <some value> 
    obj.save() 

def view2(request) 
    ... 
    obj = MyModel.objects.get_or_create(id=1) 
    obj.param2 = <some value> 
    obj.save() 

을 그리고이 견해는 두 개의 서로 다른 스레드에서 실행하는 경우 가끔 ID = 1 DB에 MyModel 인스턴스를 얻을 PARAM1 또는 PARAM2 (하지만 둘 다) 중 하나를 업데이트 - 그것은 어떤에 따라 달라집니다 과정이 처음이었다. (물론 실제 ID가 변경되지만, 때로는 2 개의 프로세스가 동일한 ID로이 두보기를 실행 함)

질문 : 업데이트 된 param1 및 param2가있는 인스턴스를 얻으려면 어떻게해야합니까? 다른 프로세스에서 변경 사항을 병합하기 위해 필요한 것이 있습니다.

한 결정은 간 잠금 객체를 생성하지만,이 경우에 나는 순서 실행 뷰를 얻을 것이다 그들은 동시에 실행 할 수 없습니다, 그래서 도움

DUPE Django: How can I protect against concurrent modification of data base entries

+2

SQLite는 일반적으로 테스트 컨텍스트 외부의 백엔드로 적합하지 않습니다. PostgreSQL 또는 MySQL 로의 마이그레이션은 최소한의 저항의 길일 것입니다. –

+1

[Django : 데이터베이스 항목의 동시 수정으로부터 어떻게 보호 할 수 있습니까?] (http://stackoverflow.com/questions/320096/django-how-can-i-protect-against-concurrent-modification-of- 데이터베이스베이스 엔트리) –

+0

흠 ...이 토론이 유용 할 수 있습니다. 내 모델에 타임 스탬프 필드를 추가하고 저장하기 전에 업데이트 할 수 있습니다. 성공한 업데이트는 다른 스레드/프로세스가 내 객체를 변경하지 않았 음을 의미하므로 save 메소드를 호출 할 수 있습니다. 그러나 업데이트가 실패한 경우 이는 다른 스레드 또는 프로세스가이를 변경 했으므로 DB에서 다시 가져 와서 병합 변경을 시도해야 함을 의미합니다. 내가 맞습니까? 추신 : 그러나 장고가 그런 문제를 해결할 수있는 것이 전혀 없다는 것이 이상합니다 ... 모든 개발자가 자신의 솔루션을 만들 수 있습니까? 매우 이상합니다. – iKiR

답변

1

SQLite는 부탁 데이터베이스에 대한 동시 액세스가 필요한 경우에는 좋지 않습니다. I MySQL의 또는 PostgreSQL을, 같은 다른 RDBMS, 전환과 같은 계정 get_or_create 취약성을 고려 제안 :

How do I deal with this race condition in django?

를 상기 링크에 관하여,이 문제에 대한 두번째 솔루션도있다 - READ 커밋 분리를 이용하여이 REPEATABLE READ 대신에 레벨. 하지만 (MySQL에서는 적어도) 테스트가 덜되었으므로 더 많은 버그/문제점이있을 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 흠 ...이 문제가 MySQL 또는 PostgreSQL에서 어떻게 해결되고 있습니까? get_or_create 정보 - 나는이 질문을 읽었고 get_or_create (관리자를 서브 클래 싱하여) 구현을 만든다. IntegrityError가 발생하면이 구현의 슈퍼 구현을 호출하고 catch하고 트랜잭션을 커밋하고 get_or_create를 다시 호출한다. SQLite에서 READ COMMITED 격리 수준을 사용하는 방법을 알려주시겠습니까? – iKiR

+0

SQLite가 전통적인 수준으로 격리 수준을 구현한다고 생각하지 않습니다. http://www.sqlite.org/sharedcache.html,하지만 잘못 될 수 있습니다. 그래도 동시 환경에서 SQLite를 사용하려면 피할 수없는 OperationalErrors를 더 잘 준비하십시오. –