2016-06-13 3 views
1

私は単純なライブラリアプリケーションを持っています。Djangoでの制御のアトミックトランザクション

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で1つのアクションとしてコミット、およびアクションのいずれかが失敗した場合にロールバックする3つのアクションを強制するために、私は次のコードの変更を行いました

私はまだこれについて何かが不足していますか?私はPython 3.4.3でDjango 1.9を使用しています。データベースはMySQLです。

+2

なぜあなたは 'AUTOCOMMIT = False'を設定していますか?それをしないでください。さもなければ、あなたは正しい考えを持っています。 –

+0

@KevinChristopherHenryがループを閉じるために、なぜ 'AUTOCOMMIT = False'がクエリに役立たないのか質問できますか?デフォルトでは 'AUTOCOMMIT = True'、' atomic'ブロックでラップされていないすべてのトランザクションについては、実行しコミットするだけですか? – bryansis2010

+0

そうです、私の答えを見てください。 –

答えて

2

お客様はtransaction.atomic()を正しく使用していますが(try ... exceptを取引外に置くことを含む)、間違いなくAUTOCOMMIT = Falseを設定する必要があります。 documentation状態として

あなたはそれが明確にあなたがtransaction.atomic()を使用しているので、あなたは、何をしたいではありません - ブタ「Djangoのトランザクション管理を無効」にしたいとき、あなたはFalseにそのシステム全体の設定を設定! documentation

これを行うと、Djangoは自動コミットを有効にせず、コミットを実行しません。基礎となるデータベース・ライブラリーの通常の動作が得られます。 これは、Djangoまたは第三者図書館によって開始されたトランザクションを含め、すべてのトランザクションを明示的にコミットする必要があります。したがって、これは、独自のトランザクション制御ミドルウェアを実行したり、本当に奇妙なことをしたい場合に最適です。

だからやめてください。 Djangoはもちろん、そのアトミックブロックの自動コミットを無効にし、ブロックが終了したときに再度有効にします。

関連する問題