0

私は単純なデータベース関係を持っています: 1 つのアイテムは多くの ItemDetails に関連しています。ItemDetails は一度にすべて更新されます。古い ItemDetails を置き換えるための ItemDetails の完全なセットを含むメッセージが HTTP POST 経由で届きます。私が使用するロジックは次のとおりです。

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

しかし、2 つの送信者が同時に更新を送信すると、競合状態になるようです。(私が思うに) delete() が 2 つのスレッドで多かれ少なかれ並行して実行されてから作成が行われるため、重複したリストが表示されることがあります。

この問題を回避するために、どのロック戦略を使用できますか? 私はPostgreSQLでDjangoを使用しています。

4

1 に答える 1

0

質問のコメントで指摘されているように、Django/Postgres の解決策の 1 つは、子をいじる前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 に答える