🎸 Django Advanced

What is Django's select_for_update and database locking?

Why Interviewers Ask This

Advanced questions like this reveal whether a candidate has internalized Django deeply enough to make architectural decisions. Strong answers demonstrate both breadth and depth of experience.

Answer

select_for_update() executes a SELECT ... FOR UPDATE SQL statement, locking the selected rows until the transaction completes — preventing other transactions from modifying or locking the same rows. Essential for avoiding race conditions in concurrent operations. Usage: from django.db import transaction @transaction.atomic def process_payment(order_id, amount): # Lock the order row exclusively try: order = Order.objects.select_for_update().get(id=order_id) except Order.DoesNotExist: raise ValueError("Order not found") if order.status != "pending": raise ValueError("Order already processed") order.status = "processing" order.save() payment_result = payment_gateway.charge(amount) order.status = "paid" if payment_result.success else "failed" order.save() return order. Options: select_for_update(nowait=True) — raise OperationalError immediately instead of waiting if locked; select_for_update(skip_locked=True) — skip already-locked rows (good for job queue: multiple workers skip rows being processed); select_for_update(of=("self",)) — lock only specific tables in a JOIN; select_for_update(no_key=True) — PostgreSQL only, weaker lock allowing FK inserts. Must be inside a transaction: @transaction.atomic or with transaction.atomic():. Deadlock prevention: always acquire locks in consistent order across all transactions. Monitor deadlocks in pg_stat_activity. Alternative — optimistic locking: version field + conditional UPDATE: updated = Order.objects.filter(pk=id, version=old_version).update(status="paid", version=old_version+1). If updated == 0, conflict occurred — retry.

Common Mistake

Candidates often give textbook answers here. Interviewers are more impressed when you relate the concept to a specific problem you solved in a real Django project.