我有PostgreSQL的Django 1.11应用程序。 看看下面的代码。
那里有可能有比赛条件吗?恐怕我可以在diff=-account.hours
上获得竞争条件。 transaction.atomic
是否可以避免竞争条件?
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)
答案 0 :(得分:1)
transaction.atomic()表示在单个事务中创建/保存所有对象,或者没有任何对象。它不会阻止帐户被其他请求修改。
您可以查看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