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.