0

同じmysqlテーブルから行を選択する5つ以上のプロセスが同時にあります。各プロセスは 100 行を選択し、選択した行を処理し、削除します。

しかし、同じ行が 2 回以上選択されて処理されています。

MYSQL 側または Ruby on Rails 側で発生しないようにするにはどうすればよいですか?

アプリは Ruby On Rails で構築されています...

4

3 に答える 3

4

テーブルはワークフローのように見えます。つまり、行の状態を示すフィールドが必要です (この場合は「要求済み」)。他のプロセスは、要求されていない行を選択する必要があります。これにより、プロセスが互いの行を踏むのを防ぐことができます。

さらに一歩進めたい場合は、プロセス識別子を使用して、何が何に取り組んでいるか、おそらくどれくらいの時間がかかりすぎているか、完了しているかどうかなどを知ることができます。

ええ、以前の質問に戻って、いくつかの回答を承認してください。あなたが間違いなく見逃したものを少なくとも 1 つ見ました。

于 2011-11-04T19:02:20.343 に答える
3

エリックの答えは良いですが、少し詳しく説明する必要があると思います...

テーブルに次のような追加の列があります。

lockhost VARCHAR(60),
lockpid INT,
locktime INT, -- Or your favourite timestamp.

それらをすべてデフォルトで NULL にします。

次に、次のようにして、ワーカー プロセスに行を「要求」させます。

UPDATE tbl SET lockhost='myhostname', lockpid=12345,
 locktime=UNIX_TIMESTAMP() WHERE lockhost IS NULL ORDER BY id
 LIMIT 100

次に、要求された行を SELECT ... WHERE lockhost='myhostname' および lockpid=12345 で処理します。

行の処理が終了したら、必要な更新を行い、lockhost、lockpid、および locktime を NULL に戻します (または削除します)。

これにより、同じ行が一度に複数のプロセスによって処理されるのを防ぎます。処理を行うホストが複数ある場合があるため、ホスト名が必要です。

バッチの処理中にプロセスがクラッシュした場合は、「locktime」列が非常に古いかどうかを確認できます (処理にかかる可能性があるよりもはるかに古い、たとえば数時間)。次に、lockhost が null でなくても、古い「locktime」を持ついくつかの行を再利用できます。

これは、データベースでよく見られる「キュー パターン」です。非常に効率的ではありません。アイテムがキューに出入りする割合が非常に高い場合は、代わりに適切なキュー サーバーの使用を検討してください。

于 2011-11-05T07:32:10.003 に答える
0

http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html

あなたのためにそれをするべきです

于 2011-11-04T17:01:08.850 に答える