Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 10 of 10 · Django Models & ORM
Interview question

How do you use database transactions and atomic() in Django? Django में database transactions और atomic() कैसे use करें?

Answer

Django's atomic() ensures a block of database operations either all succeed together or all roll back together, preventing partial updates that leave data in an inconsistent state.

from django.db import transaction

# Using atomic() as a context manager
def transfer_funds(from_account_id, to_account_id, amount):
    with transaction.atomic():
        from_account = Account.objects.select_for_update().get(id=from_account_id)
        to_account = Account.objects.select_for_update().get(id=to_account_id)

        if from_account.balance < amount:
            raise ValueError('Insufficient funds')

        from_account.balance -= amount
        from_account.save()

        to_account.balance += amount
        to_account.save()
    # If ANY exception occurs inside this block, BOTH updates roll back

# Using atomic() as a decorator - the whole function is one transaction
@transaction.atomic
def create_order(user, items):
    order = Order.objects.create(user=user)
    for item in items:
        OrderItem.objects.create(order=order, product=item['product'], qty=item['qty'])
        Product.objects.filter(id=item['product'].id).update(
            stock=models.F('stock') - item['qty'])
    return order

# select_for_update() - locks selected rows until the transaction completes,
# preventing race conditions when multiple requests modify the same rows
with transaction.atomic():
    account = Account.objects.select_for_update().get(id=1)
    account.balance += 100
    account.save()

# Nested atomic blocks use savepoints internally
with transaction.atomic():
    order = Order.objects.create(user=user)
    try:
        with transaction.atomic():  # creates a savepoint
            risky_operation()
    except SomeException:
        pass  # only the inner block rolls back, outer transaction continues

# Manually rolling back within a transaction
with transaction.atomic():
    do_something()
    if some_condition:
        transaction.set_rollback(True)  # marks the transaction for rollback

Django का atomic() यह सुनिश्चित करता है कि database operations का block या तो सब साथ succeed हों या सब साथ rollback हों, partial updates को inconsistent state में रहने से रोकता है।

from django.db import transaction

def transfer_funds(from_account_id, to_account_id, amount):
    with transaction.atomic():
        from_account = Account.objects.select_for_update().get(id=from_account_id)
        to_account = Account.objects.select_for_update().get(id=to_account_id)

        if from_account.balance < amount:
            raise ValueError('Insufficient funds')

        from_account.balance -= amount
        from_account.save()

        to_account.balance += amount
        to_account.save()
    # किसी भी exception पर दोनों updates rollback होते हैं

@transaction.atomic
def create_order(user, items):
    order = Order.objects.create(user=user)
    for item in items:
        OrderItem.objects.create(order=order, product=item['product'], qty=item['qty'])
        Product.objects.filter(id=item['product'].id).update(
            stock=models.F('stock') - item['qty'])
    return order

# select_for_update() - rows lock करता है transaction पूरी होने तक
with transaction.atomic():
    account = Account.objects.select_for_update().get(id=1)
    account.balance += 100
    account.save()

# Nested atomic blocks savepoints use करते हैं
with transaction.atomic():
    order = Order.objects.create(user=user)
    try:
        with transaction.atomic():
            risky_operation()
    except SomeException:
        pass

Was this answer clear?