2017-01-20 15 views
0

Django 1.5からDjango 1.10に移行し、コミットおよびロールバック制御がほとんどなく、データベーストランザクションが全く異なることを発見しました。Django 1.10:メイントランザクションのフェイル/ロールバック後にデータをログテーブルにコミットする

私が欲しいもの

:Djangoの1.5では

Perform series of queries in view: my_function(request) 
If all queries succeed: 
    commit 
if any query fails: 
    rollback 
    insert into log table and commit the insertion 

、私はロールバックしてこれを処理し、例外ミドルウェアにコミット:

class ExceptionMiddleware(object): 
    def process_exception(self, request, exception): 
     # do rollback 
     # insert into log table 
     # commit 

どのように私は「はdoesnのジャンゴ1.10でこれを達成することができますロールバックを行う方法と思われますか?

マイ1.10設定:

AUTOCOMMIT = True 
ATOMIC_REQUESTS = True 

これは正しく、唯一の完了時にコミットし、1つのトランザクションにすべてのクエリを置きます。

"AUTOCOMMIT = False"でさらにロールバック/コミット制御ができますが、Djangoはこれに対して次のように推奨しています。 "これは、独自のトランザクション制御ミドルウェアを実行するか、

例外が transaction.atomic()__exit__メソッドを介して伝播される
from django.db import transaction 

class LoggingMiddleware(object): 
    def __init__(self, get_response): 
     self.get_response = get_response 

    def __call__(self, request): 
     try: 
      with transaction.atomic(): 
       response = self.get_response(request) 
     except: 
      log_failure() 
      raise 
     return response 

は、トランザクションは自動的にロールバックされます。Djangoの1.10

答えて

1

次のように動作しました。 my_view()に例外がある場合、その挿入はロールバックされますが、例外ミドルウェアへの挿入はコミットされます。

settings.py

Database ATOMIC_REQUESTS = True 

MIDDLEWARE = [ 
    ... 
    'myproject.middleware.ExceptionMiddleware', # put it last 
] 

views.py

def my_view(request): 
    do table insertion insertion.. 
    x = 1/0 # cause exception 

middleware.py

from django.utils.deprecation import MiddlewareMixin 

class ExceptionMiddleware(MiddlewareMixin): 
    def process_exception(self, request, exception): 
     # can be put inside "with transaction.atomic():" for more control of rollback/commit within this function 
     log_error() # do table insertion 
     # can return some response 
+0

はい、これを使用します –

2

も、これは非常に簡単になりミドルウェアの新しいスタイルを導入しました。その後、例外をキャッチして、ビューをカプセル化するメイン・トランザクションの外部で失敗を記録できます。

+0

ありがとうございました!これを試して報告して返信します:) – user984003

+0

そして 'ATOMIC_REQUESTS'は' False'に設定することができます。 –

+0

これは機能しませんでした。ビュー内の例外は、ミドルウェアの例外ハンドラによって捕らえられませんでした。私は、settings.pyのミドルウェアスタックの上と下の両方にLoggingMiddlewareを配置しようとしました。 LoggingMiddlewareは、ビューに例外がないときに何か別のもの(そして返されたものを参照)に応答を設定できることを確認しました。 – user984003

関連する問題