事务中的Django竞争条件

png*_*iko 0 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)
Run Code Online (Sandbox Code Playgroud)

Ala*_*air 5

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
Run Code Online (Sandbox Code Playgroud)