問題:
使用 SqlDependency
類別進行 SQL Server 資料庫變更監控的應用程式可能會遇到記憶體洩漏。 過期的SqlDependency
物件會在記憶體中累積,可能會耗盡系統資源。
根本原因:
SqlDependency
建立伺服器連線並註冊表通知。 即使在依賴項刪除或資源釋放(SqlCommand
、SqlConnection
)之後,關聯的會話群組和端點仍會保留在資料庫中,從而消耗記憶體。
解決方案:資料庫清理
要回收過期 SqlDependency
物件佔用的內存,請在受影響的資料庫中執行以下 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>
Sql依賴限制:
除了記憶體管理之外,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(); // Simulate table changes. MakeTableInsertDeleteChanges(changesCount); // Allow time for change notification. Thread.Sleep(1000); } Assert.AreEqual(changesCount, changesReceived);</code>
以上是如何解決SqlDependency物件過期導致的SQL Server記憶體洩漏?的詳細內容。更多資訊請關注PHP中文網其他相關文章!