オブジェクトを保存するビューを作成しようとしていますが、例外が発生した場合はndoを保存したいと思います。これは私が試したものです:
class MyView(View):
@transation.atomic
def post(self, request, *args, **kwargs):
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
私は何を間違えていますか?例外が発生した場合でもsome_object
はまだデータベースにあります。
要約する、 @transaction.atomic
は、ビューがエラーなしで応答を生成する場合、データベースでトランザクションを実行します。自分で例外をキャッチしているので、Djangoのように見えますが、ビューはうまく実行されたようです。
例外をキャッチした場合は、自分で処理する必要があります。 Controlling Transactions
失敗した場合に適切なJSON応答を生成する必要がある場合:
from Django.db import SomeError, transaction
def viewfunc(request):
do_something()
try:
with transaction.atomic():
thing_that_might_fail()
except SomeError:
handle_exception()
render_response()
ただし、transaction.atomicで装飾された関数で例外が発生した場合、何もする必要はありません。 関数を実行する前にデコレータによって作成されたセーブポイントに自動的にロールバックします 、 as 文書化 :
atomicを使用すると、データベースの原子性が保証されるコードブロックを作成できます。コードブロックが正常に完了すると、変更がデータベースにコミットされます。例外がある場合、変更はロールバックされます。
Exceptブロックで例外がキャッチされた場合、atomicが例外をキャッチしてロールバックを実行するように例外を再生成する必要があります。
try:
some_object = SomeModel(...)
some_object.save()
if something:
raise exception.NotAcceptable()
# When the workflow comes into this condition, I think the previous save should be undome
# Whant am I missing?
except exception.NotAcceptable, e:
# do something
raise # re-raise the exception to make transaction.atomic rollback
また、さらに制御したい場合は、手動で 以前に設定されたセーブポイント にロールバックできます。
class MyView(View):
def post(self, request, *args, **kwargs):
sid = transaction.savepoint()
some_object = SomeModel(...)
some_object.save()
if something:
transaction.savepoint_rollback(sid)
else:
try:
# In worst case scenario, this might fail too
transaction.savepoint_commit(sid)
except IntegrityError:
transaction.savepoint_rollback(sid)