私はジレンマを抱えています、多分あなたは私を助けることができます.
ワーク キューとして機能するテーブルがあります。レコードが挿入され、処理する必要があります。レコードが処理されると、キューから削除されます。いくつかの制限があります:
- 任意の時点で 1 つのエンティティのみがレコードを処理できます (「エンティティ」とは、スレッド、または同じデータベースに接続する別のコンピューターを意味します)
- エンティティはやや動的です。それらは変更される可能性があります (エンティティの数または特性のいずれか)
- エンティティは 1 つのトランザクションでレコードを処理します
- 処理は並行して行われる必要があります (entity1 が batch1 を選択した場合、entity2 は、entity1 が処理を完了するのを待たずに、batch2 を並行して処理できる必要があります)。
- エンティティが処理するレコードを選択すると、これが属するレコードの「バッチ」全体が他のエンティティによって選択されてはなりません。「バッチ」と言うとき、テーブルが (論理的に) 次のように構成されていることを意味します。
- 行 1 (バッチ 1)
- 行 2 (バッチ 1)
- 行 3 (バッチ 2)
- 行 4 (バッチ 2)
- 行 5 (バッチ 2)
- .... 等々。
したがって、entity1 と entity2 の両方がテーブルから処理スライスを選択したいとします。entity1 が row1 を選択すると、entity2 は batch1 以外のもの (row1 と row2 以外のもの) を選択できます。
実際の処理が何であるかは問題ではないため、処理部分を抽象化しましょう。mysql データベースのみを使用して、処理の並列性を維持しながら、エンティティが互いに衝突するのを防ぐ方法を知りたいと思っています。
私の観点からは、非常に一般的な 2 つの方向性が見えます。
- 特定のエンティティがバッチをピッキングしたことを示す、ある種のステータス フィールドを使用します。これは将来のピッキングから除外する必要があります。このアイデアには、バッチを選択したエンティティがクラッシュした場合に、他のエンティティによる処理を再開するのが少し難しいという欠点があります。
- mysql ロックを使用すると、順次ではなく並列処理を確保することが困難になるという欠点があります。たとえば、entity1 に対して select... for update を実行できます。ただし、entity2 は同じ select... for update を実行できません。これは、必要なバッチを取得する前に最初のエンティティの処理が完了するまで待機するためです。
私は知りたいです:
- コーディング作業が最小になる方向
- ここで見逃している他の指示はありますか (エンティティはデータベースを介して以外は互いに通信できないことに注意してください)
- この種の問題の標準パターンがあれば
- この種の問題について議論している記事を教えていただければ幸いです。
- この問題を解決する最も効率的な方法は何ですか。
ここで私が持っているのは、データベースは処理のために異なるエンティティ間でテーブルを分割する必要があり、それを行う最善の方法を知りたいということです。この問題に対処するのは私が初めてだとは思いません。あなたの考えを知りたいです。また、レコードはかなり単純な基準 (たとえば、batchId) によってバッチに分割できることに注意してください。
よろしく、
アンドレイ。