Djangoのドキュメントを約transaction.atomic()
と例外これを言う:例外を処理するためにネストされたDjango transaction.atomic()を使用していますか?
https://docs.djangoproject.com/en/1.10/topics/db/transactions/#django.db.transaction.atomic
は、原子内部の例外をキャッチしないでください!上記のように
...データベースエラーをキャッチする
正しい方法は、アトミック・ブロックの周囲にあります。必要に応じて、この目的のために追加のアトミックブロックを追加します。このパターンには別の利点があります。例外が発生した場合に、どのオペレーションがロールバックされるかを明示的に区切ります。
...
"必要であれば、この目的のための余分なアトミック・ブロックを追加します。" はどのようなのように見える?これを行うことはできますか?これは「予期しない動作」を引き起こしますか?
valid = True
errors = []
objects = MyModel.objects.all()
try:
with transaction.atomic():
for obj in objects:
try:
# Update and save obj here...
except:
errors.append("obj {} had errors".format(obj.pk))
valid = False
if not valid:
raise Exception('batch update failed.')
except Exception as ex:
# Handle it..
これは次のように書いていますか?もしそうなら、なぜこれは違うのですか?トランザクションブロックがDatabaseError
(またはそのサブクラス)をキャッチした場合にのみ
valid = True
errors = []
objects = MyModel.objects.all()
try:
with transaction.atomic():
for obj in objects:
try:
with transaction.atomic(): # Here's my 'extra atomic block'
# Update and save obj here...
except:
errors.append("obj {} had errors".format(obj.pk))
valid = False
if not valid:
raise Exception('batch update failed.')
except Exception as ex:
# Handle it..
>それを前にキャッチしますか? –
最初の例では、トランザクションブロックが終了する前にエラーをキャッチするので、トランザクションロジックは何かが間違っていることを認識せず、トランザクションをロールバックしません。私はそれが今より理解できることを願っています。 –
トランザクションブロックが_any_例外で終了すると、Djangoはロールバックをトリガします。しかし、 'DatabaseError'は現在のトランザクションの問題を示しているので、その中で(最も内側の)アトミックブロックがロールバックされるまで、' DatabaseError'を捕まえるべきではありません。他の例外の場合、トランザクションをロールバックしたくない場合は、アトムブロック内でそれらを捕捉することができます。 – knbk