Search code examples
pythondjangotransactionsatomicdjango-database

Django - Rollback save with transaction atomic


I am trying to create a view where I save an object but I'd like to undo that save if some exception is raised. This is what I tried:

class MyView(View):

    @transaction.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 undone
                # What am I missing?

        except exception.NotAcceptable, e:
            # do something

What am I doing wrong? even when the exception is raised some_object is still in Database.


Solution

  • Atomicity Documentation

    To summarize, @transaction.atomic will execute a transaction on the database if your view produces a response without errors. Because you're catching the exception yourself, it appears to Django that your view executed just fine.

    If you catch the exception, you need to handle it yourself: Controlling Transactions

    If you need to produce a proper json response in the event of failure:

    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()