나는이 accounts
모델을 모든 사용자의 계정 잔액 (사용 가능한 금액)을 저장하는 내 django 프로젝트에 가지고 있습니다. 사용자의 계좌에서 거의 모든 공제는 금액 확인, 즉 사용자가 x 금액 이상을 가지고 있는지 확인합니다. 그렇다면 그 금액을 공제하십시오.select_for_update 종류의 django 1.3에서 경쟁 조건을 피하기 위해
account = AccountDetails.objects.get(user=userid)
if int(account.amount) >= fare:
account.amount = account.amount-fare
account.save()
이제 그 경쟁 조건을 피할 수 있도록, 첫 .get()
문에 잠금을 넣어합니다. 사용자가 요청을 두 번하고 응용 프로그램이 위의 코드를 두 번 동시에 실행하면 요청 중 하나가 다른 요청을 무시하게됩니다.
나는 select_for_update()이 내가 원하는 것을 정확히 알아 냈습니다. 트랜잭션이 끝날 때까지 행을 잠급니다.
account = AccountDetails.objects.select_for_update().get(user=userid)
는하지만 그것은 단지 장고 1.4에서 사용할 수 이상이고 나는 아직도 장고 1.3을 사용하고 지금 할 수없는 새 버전으로 이동하고있다. 어떤 아이디어라도 현재의 장고 버전에서 어떻게 이것을 할 수 있습니까?
+1을 모델에 추가하는 방법을 제안합니다. :) 원시 SQL 쿼리를 함께 사용하는 것을 피할 수 있습니까? – Sudipta
업데이트 된 답변보기 나는 대답이 '아니오'라고 생각한다. Django의 최신 버전에서 많은 것을 backporting하지 않아도됩니다. – aychedee
@ayechedee 설명 주셔서 감사합니다. 나는'get_locked_for_update()'를 인스턴스 메소드가 아닌 클래스 메소드로 구현하면 더 좋지 않을까 궁금해했다. 'AccountDetails.objects.get (user = userid) .get_locked_for_update()'보다 'AccountDetails.get_locked_for_update (user)'와 같이 클래스에서 호출하는 것이 더 합리적 일 것입니다. 권리? – Sudipta