2

問題: シグナル受信機は、特定の条件のモデル エントリが存在するかどうかを確認し、存在しない場合は新しいエントリを作成します。ごくまれに、エントリが重複しています。

レシーバー関数内:

try:
    my_instance = MyModel.objects.get(field1=value1, field2=sender)
except:
    my_instance = MyModel(field1=value1, field2=sender)
    my_instance.save()

の明らかな候補ですget_or_createが、そのコードをクリーンアップする以外に、get_or_createヘルプを使用するとこの問題を防ぐことができますか?

シグナルはユーザーアクションの後に送信されますが、元のリクエストが複製されているとは思われません。これは、他のアクションをトリガーしたからです。

重複は、数千回のインスタンスで数回発生しています。これは必然的に複数のリクエストによって引き起こされたものですか、それとも重複したスレッドが作成される可能性がありますか? そして、おそらく詳細なトランザクション管理を使用して、重複を防ぐ方法はありますか?

Django 1.1、Python 2.4、PostgreSQL 8.1、および Apache2 での mod_wsgi の使用。

4

2 に答える 2

2

シグナルの重複を防ぐには、ドキュメントの説明に従って、シグナル アタッチメント コードに「dispatch_uid」パラメーターを追加します。

トランザクションが開かれていることを確認してください。そうしないと、チェック (objects.get()) と作成 (save()) の間でテーブルの状態が変化する可能性があります。

于 2011-03-11T23:50:14.467 に答える
1

おそらく、この答えが役立つかもしれません。どうやら、トランザクションは適切に使用されているようget_or_createですが、私はこれを確認していません。mod_wsgi はマルチプロセスおよびマルチスレッド (両方とも構成可能) であるため、競合状態が確実に発生する可能性があります。あなたのアプリケーションで起こっていると思うのは、 に対して同じ値を生成する 2 つの別々のリクエストが起動されfield1、「重複」エントリを追加するのにちょうどいいタイミングでそれらが実行されるということです。

の組み合わせをMyModel(field1=value1, field2=sender)一意にする必要がある場合はunique_together、モデルに制約を定義して整合性をさらに高めます。

于 2011-03-11T23:23:50.390 に答える