Django 交易和竞赛情况

问题描述 投票:0回答:1

我有以下 Django 代码:

with transaction.atomic():
    items = Item.objects.all()
    for item in items:
        item.count += 1
    Item.objects.bulk_update(items, ['count'])

尽管进行了交易,此代码是否仍然包含赛车条件? 我的理解是,事务不会锁定要读取的行,因此运行相同代码的多个线程可能会读取相同的计数值,因此可能不会增加适当的次数?

sql django transactions race-condition
1个回答
0
投票

回答我自己的问题。我创建了以下测试代码,并使用 psql (PostgreSQL) 10.12

运行它
def task():
    with transaction.atomic():
        item = Item.objects.select_for_update.get(pk=1)
        item.value += 1
        item.save()


def test(request):
    item = Item.objects.update_or_create(pk=1, defaults={'value': 0})

    threads = [Thread(target=task) for foo in range(0, 10)]
    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()

    return HttpResponse('finished')

运行此代码后,我可以确认它包含赛车条件,并且 Item 表中的结果值通常小于 10

© www.soinside.com 2019 - 2024. All rights reserved.