Code Reference

Transactions / ORM

Django · Reference cheat sheet

Transactions / ORM

Django · Reference cheat sheet


📋 Overview

Wrap multi-step writes in transactions so they commit or roll back together. Use transaction.atomic() (decorator or context manager). Understand autocommit (default), savepoints, on_commit hooks, and isolation when concurrent updates matter.

🔧 Core concepts

APIRole
atomic()Transaction / savepoint
on_commit(func)Run after successful commit
set_rollback(True)Mark atomic block to roll back
AutocommitEach query commits unless atomic
select_for_update()Row locks inside atomic
RobustNested atomics create savepoints

DB-specific: PostgreSQL supports durable transactions and richer locking.

💡 Examples

Atomic block:

from django.db import transaction


@transaction.atomic
def transfer(from_acct, to_acct, amount):
    from_acct.balance -= amount
    from_acct.save(update_fields=["balance"])
    to_acct.balance += amount
    to_acct.save(update_fields=["balance"])

on_commit (side effects):

def create_order(data):
    with transaction.atomic():
        order = Order.objects.create(**data)
        transaction.on_commit(lambda: send_order_email(order.pk))
        return order

Locking:

with transaction.atomic():
    item = (
        Product.objects.select_for_update()
        .get(pk=pk)
    )
    if item.stock < 1:
        raise InsufficientStock()
    item.stock -= 1
    item.save(update_fields=["stock"])

Catch integrity errors:

from django.db import IntegrityError

try:
    with transaction.atomic():
        Tag.objects.create(slug=slug)
except IntegrityError:
    ...

⚠️ Pitfalls

  • Long atomic blocks holding locks—keep them short.
  • Catching exceptions inside atomic without re-raising can leave the transaction broken until exit.
  • Side effects (email, HTTP) inside atomic that run even if later rollback—use on_commit.
  • select_for_update outside atomic is an error on some backends.
  • Assuming read-after-write visibility across connections without commit.

On this page