交易中的Django竞争条件

时间:2018-01-22 14:33:53

标签: python django postgresql

我有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)

1 个答案:

答案 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