1

私は、リアルタイムでユーザーを一致させるために構築しようとしているシステムを持っています。特定の基準に基づいて、ユーザーは1対1で照合されます。次のデータベーステーブルがあります(チャットルーレットタイプのシステムのようなものです)。

Pool
+UserId
+Gender
+City
+Solo (bool)

Matched
+UserId
+PartnerId

ユーザーが特定のページに入ると、trueに設定されてPoolテーブルに追加Soloされます。次に、システムはテーブルにクエリを実行して別のユーザーを検索し、true(パートナーがいないことを意味します)であり、クエリしたものと等しいPool結果を返します。一致が返された場合は、両方のユーザーをデータベースに入れ、テーブルの両方の列をに変更します。接続が切断されると、テーブルから削除され、列がに変わります。スレッドセーフで同時実行性でこれが機能する方法を設計しようとすると、問題が発生します。これが私が立ち往生したいくつかの質問です:SoloGenderCityMatchedSoloPoolfalseMatchedSolotrue

-2人のユーザーPoolが同時にデータベースにクエリを実行し、両方が同じ「ソロ」ユーザーを返す場合はどうなりますか?これを防ぐにはどうすればよいですか?

-1人のユーザーPoolがユーザーのsolo列が変更される前にクエリを実行した場合、そのユーザーは結果セットに返されますが、技術的にはソロではありません。

-他にどのような並行性/スレッドセーフの問題に直面していますか?これより良い方法はありますか?

4

3 に答える 3

1

問題の一部は、「ソロ」フィールドが冗長であるということだと思います。「一致した」テーブルに有効なエントリがあるかどうかを示すだけです。それを削除し、代わりに「プール」テーブルを「一致」テーブルに結合することをお勧めします。これにより、2つの同期を維持する際の問題について心配する必要がなくなります。

その他の同時実行の問題は、同時実行追跡​​フィールドを使用することで解決できます。ASP.NETMVCアプリケーションでのEntityFrameworkによる同時実行の処理を参照してください。

また、私の意見ですが、単にエントリを削除するのではなく、削除されたエントリを保存するための「監査」タイプのテーブルを使用するか、「一致」に一時テーブルを使用するように切り替えることを検討してください。その情報は、将来、マッチングアルゴリズムなどを微調整するために非常に役立つ可能性があります。

于 2012-09-04T19:13:17.380 に答える
1

これを解決する非常に簡単な方法は、アルゴリズムをトランザクションでラップし、分離レベルをシリアル化可能に設定し、デッドロックが発生した場合にビジネス操作全体を再試行することです。これにより、質問のすべての懸念が解決されるはずです。

このような複雑なケースでは、アプリケーションをデッドロック耐性にするのは簡単ではありません。データベースのロックと同時実行を始めたばかりだと思います。このソリューションは完璧ではありませんが、十分である可能性があります。

より高度な機能が必要な場合は、悲観的なロックに関する調査を行う必要があります。

于 2012-09-04T20:20:11.020 に答える
0

キューイングは良い考えです。一致の各要求がキューに入れられた場合、プールを照会するための競合やデッドロックは発生しません。

于 2012-09-04T19:24:08.760 に答える