2011-06-30 3 views
1

Ploneで_createObjectByTypeを使用する必要があります。私は引数としてオブジェクトのidを持っています。このシナリオでは、衝突を避けるためにtime.time()に基づくIDを作成することは安全ですか? 2つのリクエストは、time.time()のように正確に同じタイムスタンプを持つことができますか?プログラムでploneでコンテンツタイプを作成する場合、time.time()は安全な方法ですか?

答えて

5

万一、まれに2つのリクエストがまったく同時に処理されても、競合が発生した場合、ZODBはConflictErrorを発生させてリクエストを再試行します。以下の議論への対応

:defition両方のトランザクションによって、単一のコンピュータ上で

は(各スレッドにあなたはtime.time(から同じ結果を得ました)。)重複する必要がありますZODBはMVCCあるので、各スレッドが見ていますトランザクションが開始されたときと同じようにデータベースの一貫性のあるビュー。 2番目のスレッドがコミットすると、トランザクションの開始以降に変更されたオブジェクトに書き込むため、競合エラーが発生します。

複数のコンピュータでクライアントを実行している場合、クライアント間のクロックドリフトの可能性について考える必要があります。トランザクションIDについては、ZODBは現在のタイムスタンプまたは最後のトランザクションID + 1のどちらか大きい方を選択します。

ただし、おそらく、タイムスタンプをIDとして使用しないでください。競合が発生する可能性がありますすべての要求が同じBTreeバケットにエントリを作成したいので、負荷が重いランダムにIDを取り出すことで、ほとんどすべての競合が解消されますが、非効率的にいっぱいのBTツリーが生成されます。推奨されるアプローチは、オブジェクトを作成する各スレッドが、数値空間のランダムな点から開始し、IDを順番に作成することです。 idがすでに使用されていることが分かった場合は、数字スペースの別のポイントをランダムに選択し、そこから再び開始する必要があります。私はzope.intidがこの戦略の実装を含んでいると信じています。

+0

私は競合エラーについて正確に考えていました。それが発生した場合、どのように要求を再試行しますか?要求は失われていないのですか? –

+0

いいえ、Plone(Zopeは実際には)競合エラーがあったため、Zopeは要求を処理しているので、要求が失われないため、再試行します。 – vangheem

+1

私は、あなたが競合のエラー状況に遭遇するのではないかと疑います。代わりに、1つのリクエストは、すでに使用中のIDに関する例外を受け取ります。 –

関連する問題