0 day streak
python / intermediate
Snippet

Django Database Transactions with atomic()

atomic() ensures all operations succeed or all fail together - critical for financial data. select_for_update() locks rows to prevent race conditions during concurrent modifications.

snippet.py
python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
from django.db import transaction
from .models import Account, Transaction
def transfer_funds(source_id, target_id, amount):
try:
with transaction.atomic():
source = Account.objects.select_for_update().get(id=source_id)
target = Account.objects.select_for_update().get(id=target_id)
if source.balance < amount:
raise ValueError('Insufficient funds')
source.balance -= amount
target.balance += amount
source.save()
target.save()
Transaction.objects.create(
account=source,
amount=-amount,
transaction_type='TRANSFER'
)
Transaction.objects.create(
account=target,
amount=amount,
transaction_type='TRANSFER'
)
except ValueError:
return False
return True
django
Breakdown
1
transaction.atomic()
Creates a transaction block that rolls back on any error
2
select_for_update()
Locks selected rows until transaction completes
3
raise ValueError()
Triggers automatic rollback when funds are insufficient