これが私のシナリオです:
- それぞれにマルチスレッド メッセージ キューイング コンシューマーを備えた 2 つのサーバーがあります (合計 2 つのコンシューマー)。
- 多くのメッセージ タイプ (CreateParent、CreateChild など) があります。
- 悪いレガシ コードで立ち往生しています (子を作成すると、部分的に親が作成されます。悪いことはわかっていますが、それを変更することはできません。)
- メッセージの順序を仮定することはできません (メッセージのキューイングの原則!)
- RabbitMQ は、私のメッセージ キューイング ブローカーです。
私の問題:
- 2 つのスレッドが同時に実行されている場合 (1 つは CreateParent を実行し、もう 1 つは CreateChild を実行)、2 つのスレッドがデータベースに Parent を作成しようとするため、競合が発生します (レガシー コードを思い出してください!)。
私の最初の解決策:
- コンシューマの内部では、「エンティティ ロック」の概念を作成しました。たとえば、スレッドが CreateChild メッセージを処理するとき、CreateParent メッセージの処理が待機できるように、子と親 (レガシー コード!!) をロックします。基本的な .net Monitor と Id のリストを使用して、この概念を実装しました。それはうまくいきます。
私の最初のソリューションの制限:
- 私の「エンティティ ロック」の概念は、1 つのサーバー上の 1 つのプロセス内の 1 つのコンシューマーに対してうまく機能します。ただし、複数のコンシューマーを実行している複数のサーバー間では機能しません。
- 共有データベースを使用してエンティティ ロックの概念を「保存」することを考えているため、各プロセス (およびスレッド) がデータベースにアクセスして、どのエンティティがロックされているかを確認できます。
私の質問(ついに!):
これらすべてが非常に複雑になり、バグのリスクとコードのメンテナンスの問題が増加しています。私は本当にそれが好きではない! 誰かがすでにこの種の問題に直面していますか? それらは許容できる回避策ですか?私のシナリオのクリーンなソリューションのアイデアはありますか?
ありがとう!