📄

About Django's transaction.atomic

This article was automatically translated from theJapanese original by AI. It may contain translation errors.

This post was published over 2 years ago. Its content may be outdated.

I’d sort of seen it around but didn’t understand it, so I looked into it a bit. Please point out anything I’ve gotten wrong.

TL;DR

To put it briefly, by using transaction.atomic you can roll back changes to the DB when an error occurs partway through the processing.

About transaction.atomic

Let me explain with the common bank example: suppose I write code to move money between accounts. (You should never write code like this in production ())

def money_idou():
   meron_kouza = Kouza.objects.get(name="meron")
   itigo_kouza = Kouza.objects.get(name="itigo")
 
   # Move 150 yen from the `melon account` to the `strawberry account`
   itigo_kouza.amount = itigo_kouza.amount - 150
   itigo_kouza.save()
   meron_kouza.amount = meron_kouza.amount + 150
   meron_kouza.save()

Suppose there’s a Kouza (account) model that has name (account name) and amount (balance).

I moved money by adding 150 yen to the melon account and subtracting 150 yen from the strawberry account. If some kind of error occurs while moving the money, it could happen that the processing ends after the amount has been subtracted from the strawberry account but before it’s added to the melon account. transaction.atomic is what lets you undo the subtraction from the strawberry account when an error occurs.

Using transaction.atomic

from django.db import transaction
  
 # here
+@transaction.atomic()
 def money_idou():
    meron_kouza = Kouza.objects.get(name="meron")
    itigo_kouza = Kouza.objects.get(name="itigo")
  
    # Move 150 yen from the `melon account` to the `strawberry account`
    itigo_kouza.amount = itigo_kouza.amount - 150
    itigo_kouza.save()
    meron_kouza.amount = meron_kouza.amount + 150
    meron_kouza.save()

If you attach @transaction.atomic() as a decorator on a function, the transaction applies across the entire function. To use it partially, write it as follows.

from django.db import transaction
  
 # here
-@transaction.atomic()
 def money_idou():
    meron_kouza = Kouza.objects.get(name="meron")
    itigo_kouza = Kouza.objects.get(name="itigo")
  
    # Move 150 yen from the `melon account` to the `strawberry account`
+    with transaction.atomic():
+        itigo_kouza.amount = itigo_kouza.amount - 150
+        itigo_kouza.save()
+        meron_kouza.amount = meron_kouza.amount + 150
+        meron_kouza.save()

Summary

By using transaction.atomic, you can roll back changes to the DB when an error occurs partway through the processing.

References

Recent Articles

Network(beta)

Drag to move / Ctrl+wheel to zoom