Django database transaction atomic

created:

updated:

tags: django

I recently learned that in Django, there’s a decorator or context manager we can use to ensure the atomicity of database transaction.

According to Django’s documentation, we can use @transaction.atomic and it allows us to create a block of code where the atomicity on database is guaranteed. Also, what’s good seems that if there is an exception, the changes are rolled back.

With a decorator

from django.db import transaction


@transaction.atomic
def viewfunc(request):
    # This code executes inside a transaction.
    do_stuff()

With a context manager:

from django.db import transaction


def viewfunc(request):
    # This code executes in autocommit mode (Django's default).
    do_stuff()

    with transaction.atomic():
        # This code executes inside a transaction.
        do_more_stuff()

With try/except

Further, we can wrap atomic in a try/except block:

from django.db import IntegrityError, transaction


@transaction.atomic
def viewfunc(request):
    create_parent()

    try:
        with transaction.atomic():
            generate_relationships()
    except IntegrityError:
        handle_exception()

    add_children()

In the above example, if generate_relationships() cause a database error, we can still execute queries in add_children() as well as the changes from create_parent() are still there. However, any operations attempted in generate_relationships() will be rolled back safely when handle_exception() is called.

May need manual revert model state when rolling back a transaction

Reference