Reputation: 1297
I have Django 1.11 app with PostgreSQL. Take a look at code below.
Is it possible to have race condition there? I am afraid I could get race condition on diff=-account.hours
. Does transaction.atomic
save from race condition?
from django.db import transaction
def write_off(account_ids):
accounts = Account.objects.filter(id__in=account_ids)
for account in accounts:
with transaction.atomic():
MyLog.objects.create(
hours=0,
operation_type=LOG_OPERATION_WRITE_OFF,
diff=-account.hours,
)
Account.objects.filter(pk=account.pk).update(hours=0)
Upvotes: 0
Views: 1907
Reputation: 308839
The transaction.atomic() means that all your objects are created/saved in a single transaction, or none of them are. It does not prevent the accounts being modified by another request.
You could look at select_for_update
:
def write_off(account_ids):
with transaction.atomic():
accounts = Account.objects.select_for_update().filter(id__in=account_ids)
for account in accounts:
MyLog.objects.create(
hours=0,
operation_type=LOG_OPERATION_WRITE_OFF,
diff=-account.hours,
)
accounts.update(hours=0) # use fewer queries by updating all accounts at once
Upvotes: 5