期限切れの SqlDependency オブジェクトによって引き起こされる SQL Server のメモリ リークに対処する
問題:
SqlDependency
オブジェクトを使用すると、SQL Server のメモリ使用量が着実に増加する可能性があります。 これは、SqlDependency.Stop()
を呼び出して SqlCommand
と SqlConnection
を解放した後でも、データベースには会話グループとエンドポイントが保持されるためです。 この蓄積は最終的に、特に SQL Server Express でメモリの枯渇につながります。
解決策:
次の SQL スクリプトは、これらの期限切れの会話エンドポイントをクリーンアップします:
<code class="language-sql">DECLARE @ConvHandle uniqueidentifier DECLARE Conv CURSOR FOR SELECT CEP.conversation_handle FROM sys.conversation_endpoints CEP WHERE CEP.state = 'DI' or CEP.state = 'CD' OPEN Conv; FETCH NEXT FROM Conv INTO @ConvHandle; WHILE (@@FETCH_STATUS = 0) BEGIN END CONVERSATION @ConvHandle WITH CLEANUP; FETCH NEXT FROM Conv INTO @ConvHandle; END CLOSE Conv; DEALLOCATE Conv;</code>
メモリ リークが発生しているデータベースに対してこのスクリプトを実行します。
SqlDependency の制限:
SqlDependency
は完璧ではないことを理解することが重要です。一部のテーブル変更、特に再サブスクリプション プロセス中に発生した変更が見逃される可能性があります。
より良いアプローチ: SqlDependencyEx
より堅牢で信頼性の高いソリューションについては、オープンソースの代替手段である SqlDependencyEx
の使用を検討してください。 データベース トリガーと Service Broker 通知を活用して、より効果的な変更イベント処理を実現します。 以下に例を示します:
<code class="language-csharp">int changesReceived = 0; using (SqlDependencyEx sqlDependency = new SqlDependencyEx( TEST_CONNECTION_STRING, TEST_DATABASE_NAME, TEST_TABLE_NAME)) { sqlDependency.TableChanged += (o, e) => changesReceived++; sqlDependency.Start(); // Make table changes. MakeTableInsertDeleteChanges(changesCount); // Wait a little bit to receive all changes. Thread.Sleep(1000); } Assert.AreEqual(changesCount, changesReceived);</code>
SqlDependencyEx
は、優れた変更追跡を提供し、標準の SqlDependency
に関連するメモリの問題を排除します。
以上が期限切れの SqlDependency オブジェクトをクリーンアップして SQL Server のメモリ リークを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。