我们正在尝试诊断上周在我们的生产环境中发生的问题。简而言之,数据库连接池似乎充满了我们的ASP.NET 3.5应用程序中的活动连接,即使在重新启动应用程序池和IIS之后也无法清除。
高级DBA表示,由于网络连接发生在操作系统级别,回收应用程序和IIS并没有切断实际的网络连接,因此SQL Server离开了数据库连接以继续运行,我们的应用程序仍然无法到达数据库。
在查找强制数据库连接池重置的方法时,我找到了静态方法SqlConnection.ClearAllPools()
,文档说明了它的作用,但很少或没有解释何时调用它。似乎在Application_Start
的开头调用它并且我的global.asax.cs中Application_End
的结尾是一个很好的安全措施来保护应用程序免受有毒连接池的影响,尽管它当然会招致启动/关闭时间会影响性能。
我所描述的是一个好习惯吗?还有更好的吗?目标是允许一个简单的应用程序重新启动来重置应用程序的错位连接池,而不必重新启动操作系统或SQL Server服务,这将影响许多其他应用程序。
非常感谢任何指导。
答案 0 :(得分:2)
当进程终止时,所有网络连接始终始终始终立即关闭。这是在TCP级别。与ADO.NET无关,适用于所有应用程序。杀死浏览器,所有下载停止。杀死FTP客户端,所有连接立即关闭。
此外,连接池是每个进程。所以在启动应用程序时清除它是没用的,因为池是空的。无需在关机时清除它,因为所有连接都会(正常)关闭。
可能您的应用未返回与池的连接。在所有情况下,您必须处理所有连接。如果你不这样做,悬空连接将无限期累积。
清除池不会释放悬空连接,因为它们似乎正在使用中。 ADO.NET怎么能告诉你再也不会使用它们了?它不能。
查看sys.dm_exec_connections
以查看谁正在打开连接。您可以将ADO.NET池大小增加为一种权宜之计。 SQL Server每个实例可以接管超过30k的连接。你通常永远不会让它饱和。