问题:
使用 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中文网其他相关文章!