पाठ 20 / 26

Transactions and Referential Protection

All or nothing; no orphaned rows.

transaction.atomic and on_delete=PROTECT

transaction.atomic() wraps several writes so they commit together or roll back together when an exception occurs. Combine it with database constraints (unique, foreign keys) to keep data consistent even when application code has bugs. on_delete=PROTECT raises ProtectedError instead of deleting a category that still has products. Consider ATOMIC_REQUESTS or explicit atomic blocks around multi-step operations such as creating an order with its items.

A rolled-back transaction and a protected delete, run

I ran this script with python manage.py shell --no-imports in the demo project (Django 6.1.1, SQLite). Creating a category and product, then a duplicate category name, raises IntegrityError: the whole block rolls back, so the product count and the Toys category are unchanged. Deleting a category with products raises ProtectedError.

from decimal import Decimal
from django.db import IntegrityError, transaction
from catalog.models import Category, Product

before = Product.objects.count()
try:
    with transaction.atomic():
        toys = Category.objects.create(name="Toys")
        Product.objects.create(category=toys, name="Yo-yo", price=Decimal("99"))
        Category.objects.create(name="Office")          # violates unique=True -> error
except IntegrityError as e:
    print("rolled back:", type(e).__name__)
print("products before/after:", before, Product.objects.count())
print("Toys exists:", Category.objects.filter(name="Toys").exists())
try:
    Category.objects.get(name="Office").delete()
except Exception as e:
    print(type(e).__name__, "- PROTECT keeps products from losing their category")

Output:

rolled back: IntegrityError
products before/after: 4 4
Toys exists: False
ProtectedError - PROTECT keeps products from losing their category

Keep external calls outside transactions

Do not call payment or email APIs inside atomic blocks; use transaction.on_commit to trigger them after a successful commit.

त्वरित जाँच: What happens to earlier writes in an atomic block when a later write fails?

  • They stay committed
  • They are rolled back too
  • They are duplicated
  • They are written to a log only
Answer

They are rolled back too — All or nothing.