0

我有一个简单的数据库关系:一个 Item 与许多 ItemDetails 相关。ItemDetails 会立即更新:一条消息通过 HTTP POST 传入,其中包含完整的 ItemDetails 集,以替换任何旧的 ItemDetails。我使用的逻辑是这样的:

with transaction.atomic():
    ...
    ItemDetails.objects.filter(item_id=item_id).all().delete()
    for item in new_item_list:
        ItemDetails.objects.create(title=item.title, ...)

但是,如果两个发件人同时发送更新,这似乎有一个竞争条件。我有时会看到重复的列表,因为(我认为)delete() 在或多或少并行的两个线程上运行,然后创建发生。

我可以使用什么锁定策略来避免这个问题?我正在将 Django 与 PostgreSQL 一起使用。

4

1 回答 1

0

正如问题评论中所指出的,一种 Django/Postgres 解决方案是在与孩子们相处之前select_for_update()在正确的行上使用。Item这会导致 Django 阻塞等待锁。因此,将逻辑更改为以下可修复竞争条件:

with transaction.atomic():
    # Just add this and Django will block here until other threads let go.
    item = Item.objects.select_for_update().get(pk=item_id)
    ...
    ItemDetails.objects.filter(item_id=item_id).all().delete()
    for item in new_item_list:
        ItemDetails.objects.create(title=item.title, ...)
于 2014-08-26T13:48:18.963 回答