2016-06-13 2 views
1

나는 간단한 라이브러리 응용 프로그램을 가지고 있습니다.장고의 제어 원자 트랜잭션

settings.py에서 :

AUTOCOMMIT=False 

from django.db import IntegrityError, transaction 
    class CreateLoan(forms.Form): 
     #Fields... 
     def save(self): 
      id_book = form.cleaned_data.get('id_book', None) 
      id_customer = form.cleaned_data.get('id_customer', None) 
      start_date = form.cleaned_data.get('start_date', None) 
      book = Book.objects.get(id=id_book) 
      customer = Customer.objects.get(id=id_customer) 
      new_return = Return(
       book=book 
       start_date=start_date) 
      txn=Loan_Txn(
       customer=customer, 
       book=book, 
       start_date=start_date 
      ) 

      try 
       with transaction.atomic(): 
        book.update(status="ON_LOAN") 
        new_return.save(force_insert=True) 
        txn.save(force_insert=True) 
      except IntegrityError: 
       raise forms.ValidationError("Something occured. Please try again") 
forms.py에서 하나 개의 동작으로 저지하고, 작업 중 하나가 실패 할 경우 롤백 3 개 작업을 강제하기 위해, 나는 다음과 같은 코드를 변경했다

나는 이것에 관해서 아직도 아무것도 놓치고 있냐? 나는 장고 1.9를 파이썬 3.4.3과 함께 사용하고 있으며 데이터베이스는 MySQL이다.

+2

왜 'AUTOCOMMIT = False'를 설정하고 있습니까? 그러지 마. 그렇지 않으면 올바른 아이디어를 얻었습니다. –

+0

@KevinChristopherHenry가 루프를 닫으면, 왜'AUTOCOMMIT = False'가 쿼리에 도움이되지 않는지 질문 할 수 있습니까? 기본적으로'AUTOCOMMIT = True'라고하고,'atomic' 블록으로 싸여 있지 않은 모든 트랜잭션에 대해서 그들은 실행하고 커밋 할 것이라고 말하는 것이 맞습니까? – bryansis2010

+0

맞습니다. 자세한 내용은 제 답변을 참조하십시오. –

답변

2

try ... except을 거래 외부에 넣는 것을 포함하여 transaction.atomic()을 올바르게 사용하고 있지만 반드시 AUTOCOMMIT = False을 설정하지 않아야합니다.

documentation 상태로, 당신은 당신이 명확하게 하지입니다 -하지만 "장고의 트랜잭션 관리를 해제"할 때 False 해당 시스템 전체 설정을 설정 당신이 transaction.atomic()을 사용하고 있기 때문에 당신이하고 싶어! documentation :

이렇게하면 Django는 자동 커밋을 사용하지 않으며 커밋을 수행하지 않습니다. 기본 데이터베이스 라이브러리의 일반 동작을 가져옵니다. 이렇게하면 Django 또는 타사 라이브러리에서 시작한 트랜잭션을 명시 적으로 커밋해야합니다. 따라서이 기능은 자신 만의 트랜잭션 제어 미들웨어를 실행하거나 정말로 이상한 일을하고 싶은 상황에서 사용하는 것이 가장 좋습니다.

그렇게하지 마십시오. Django는 물론 그 원자 블록에 대한 자동 커밋을 비활성화하고 블록이 끝나면 다시 활성화합니다.