0

いくつかのxmlフィード解析を行うツイストデーモンがあります。

IIRCがpsycopg2をラップしているtwisted.enterprise.adbapiを介してデータをPostgreSQLに保存します

データベースにデータを保存する際にいくつかの問題が発生しました。重複するデータが定期的にデータベースに取り込まれます。

正直なところ、私の実装にはいくつかの根本的な問題があり、それをやり直して、はるかに優れた設計にする必要があります。ただし、それを行うための時間とリソースが不足しています。そのため、今のところ「実行し続ける」モードになっています。

この問題は、deferToThreadの使用法、または最初にサーバーを生成した方法のいずれかから発生する可能性があると思います。

機能の概要として、私が間違っていると思うのは次のとおりです。

ツイストは、分析する必要のあるアカウントのPostgresをクエリし、それらにブロックを設定します

SELECT 
    id 
FROM 
    xml_sources 
WHERE 
    timestamp_last_process < ( CURRENT_TIMESTAMP AT TIME ZONE 'UTC' - INTERVAL '4 HOUR' ) 
    AND
    is_processing_block IS NULL ;

lock_ids = [ i['id'] for i in results ]

UPDATE xml_sources SET is_processing_block = True WHERE id IN %(lock_ids)s

私が起こっていると思うのは、(偶然に)複数のサーバーが実行されているか、他のさまざまな問題が発生すると、複数のスレッドがこのデータを処理することです。

このクイックセクションを専用のテーブルロックでラップすると、これは修正される可能性があります(または、少なくとも問題として除外される可能性があります)。

でも、ツイストでテーブルロックをしたことはありません。誰かが私を正しい方向に向けることができますか?

4

1 に答える 1

1

SELECT FOR UPDATEプレーンの代わりに実行できSELECTます。これにより、クエリによって返される行がロックされます。実際にテーブルロックが必要な場合は、ステートメントを発行するだけですがLOCK、残りの質問に基づいて、行ロックが必要だと思います。

を使用している場合、トランザクションで複数のステートメントを実行する場合はadbapiを使用する必要があることに注意してください。runInteractionに渡される関数はrunInteractionスレッドで実行されるため、データベースの相互作用を使用するcallFromThreadblockingCallFromThread、データベースの相互作用からreactorに戻る必要がある場合があります。

ただし、ロックは問題にならない場合があります。一つには、あなたがとを混ぜているならdeferToThreadadbapi何かが間違っている可能性があります。 すでにあなたのためadbapiに同等のことをしています。メインスレッドですべてを実行できるはずです。deferToThread

ただし、より具体的な回答については、代表的な例を含める必要があります。あなたの質問を考えてみてください。それは基本的に「時々、私は自己認めて問題のある実装で重複データを取得します。それは大きく、修正できず、またあなたに見せることもできません。」これは答えることができる質問ではありません。

于 2012-09-12T23:28:37.227 に答える