14

データベースの行を継続的に監視して、変更 (更新) を確認する必要があります。他のソースからの変更または更新がある場合、アプリケーションでイベントを発生させる必要があります (私は WCF を使用しています)。変更のためにデータベース行を継続的にリッスンする方法はありますか?

同じテーブル内の異なる行を監視するために、より多くのイベントが発生している可能性があります。パフォーマンスの場合に問題はありますか。C# Web サービスを使用して SQL Server バックエンドを監視しています。

4

6 に答える 6

9

それぞれのテーブルでAFTERUPDATEトリガーを使用して、SQL ServerServiceBrokerキューにアイテムを追加できます。次に、キューに入れられた通知をWebサービスに送信します。

別のポスターがSqlDependencyについて言及しましたが、これも言及しようと思いましたが、MSDNのドキュメントは、Windowsクライアントの例を提供するだけでなく、次のアドバイスも提供するという点で少し奇妙です。

SqlDependencyは、データベースに対してアクティブな依存関係を持つサーバーの数が比較的少ないASP.NETまたは中間層サービスで使用するように設計されています。数百または数千のクライアントコンピューターで単一のデータベースサーバー用にSqlDependencyオブジェクトが設定されるクライアントアプリケーションで使用するようには設計されていません。

参照

于 2010-01-28T05:46:54.980 に答える
5

少し前に非常によく似た要件があり、CLR SP を使用してデータをメッセージ キューにプッシュすることで解決しました。

展開を容易にするために、メッセージ キューにメッセージをプッシュするだけの小さな関数を呼び出した CLR SP を作成SendMessageし、AFTER INSERT トリガー (CLR トリガーではなく通常のトリガー) を使用してそれをテーブルに結び付けました。

この場合、パフォーマンスが私の主な関心事でしたが、ストレステストを行ったところ、私の期待を大幅に上回りました。また、SQL Server Service Broker と比較すると、展開が非常に簡単なソリューションです。CLR SP のコードも非常に簡単です。

于 2010-02-27T10:34:43.757 に答える
2

テーブルからのデータの挿入/更新/削除に成功した後に、CLR 関数またはサービスを呼び出すようなもののアイデアを熟考しました。この状況でもそれでいいの?

おそらくそれは良い考えではありませんが、それでもテーブル トリガー地獄に入るよりはましだと思います。

あなたの問題は、データを変更するたびに何かをしたい、たとえば、何らかの値を再計算したいということだと思います。データベースにこれを任せるのは、パフォーマンスに深刻な影響を与える可能性があるため、お勧めできません。

さまざまなテーブルでの挿入、更新、削除を検出したいとおっしゃいました。あなたが傾倒している方法でそれを行うと、テーブルごとに3つのトリガー/CLR関数をセットアップし、それらにイベントをWCFサービスに投稿させる必要があります(SQLサーバー内で利用可能な.netのサブセットでもサポートされていますか?)。WCF サービスは、受信したイベントに基づいて適切なアクションを実行します。

この問題のより良い解決策は、データ変更を検出する責任をデータベースからアプリケーションに移すことです。これは、実際には非常に簡単かつ効率的に実装できます。

各テーブルには、主キー (int、GUID など) と、エントリが最後に更新された日時を示すタイムスタンプ列があります。これは、オプティミスティック コンカレンシーのシナリオで非常に頻繁に見られるセットアップであるため、スキーマ定義を更新する必要さえない場合があります。ただし、この列を追加する必要があり、タイムスタンプの更新をデータベースを使用するアプリケーションにオフロードできない場合は、テーブルごとに 1 つの更新トリガーを記述し、各更新後にタイムスタンプを更新するだけで済みます。

変更を検出するために、WCF サービス/監視アプリケーションは、特定の時間間隔で主キー/タイムスタンプのペアを使用してローカル ディクショナリ (できればハッシュテーブル) を作成します。データベースのカバレッジ インデックスを使用すると、この操作は非常に高速になります。次のステップは、辞書と出来上がりの両方を比較することです。

ただし、このアプローチにはいくつかの注意点があります。それらの 1 つはテーブルごとのレコードの合計、もう 1 つは更新頻度 (低くなりすぎると効果がありません)、さらにもう 1 つのピンポイントは、変更/挿入の前にデータにアクセスする必要があるかどうかです。

お役に立てれば。

于 2010-02-23T18:44:59.033 に答える
2

「継続的に」監視するとは、数時間、数分、数秒、さらには数ミリ秒ごとに監視することを意味します。このソリューションは、ミリ秒単位の更新では機能しない可能性があります。ただし、テーブルを 1 分間に数回「監視」するだけでよい場合は、外部プロセスでテーブルの更新をチェックするだけで済みます。(DateTime 列が存在する場合。)その後、変更された行または新しく追加された行を処理し、必要な通知を実行できます。したがって、変更をリッスンするのではなく、変更をチェックすることになります。この方法でチェックを行う利点の 1 つは、一定の時間内に多くの行が更新された場合に、それらをまとめて一括処理するため (それぞれに応答するのではなく)、パフォーマンスが低下するリスクが少ないことです。およびすべての変更は個別に行われます。)

于 2010-02-21T06:19:01.407 に答える
1

SQL Server 通知サービスを使用しませんか? それがまさにあなたが探しているものだと思います。通知サービスのドキュメントに目を通して、それが要件に合っているかどうかを確認してください。

于 2010-02-24T17:43:55.260 に答える
0

ここには素晴らしいアイデアがあると思います。スケーラビリティの観点からは、チェックを外部化すること (たとえば、Paul Sasik の回答) がおそらくこれまでで最高のものだと思います (彼に +1)。

何らかの理由でチェックを外部化したくない場合は、HttpCache を使用してウォッチャーとコールバックを保存するという別のオプションがあります。

つまり、監視したいレコードを DB に入れるときは、(.Add メソッドを使用して) キャッシュにも追加し、その上に SqlCacheDependency を設定し、必要なときに呼び出したいロジックへのコールバックを設定します。依存関係が呼び出され、アイテムがキャッシュから排出されます。

于 2010-02-26T13:40:19.407 に答える