现在您必须决定要采取的措施,我不建议您告诉用户您已经用完了所有连接。有些应用程序会通知用户系统正忙于帮助其他客户,并建议用户稍后进行访问。其他应用程序则播放一段动画,通知用户系统尚未死锁,而是正在忙于处理他们的请求。同时,您的代码重新尝试操作。在所有情况下,您应该记录这些故障,以便帮助诊断问题的症结所在,并记录您已经耗尽了资源。
监视连接池
您已经打开和关闭了一个连接,现在您希望知道该连接是否仍然处于打开状态。您可以使用几种方法来确定有多少连接仍然处于打开状态,以及它们正在执行何种操作:
现在我们将讨论如何查找连接池计数器,以及如何使用这些监视方法。
连接池计数器在哪里? 要监视连接池计数器,您必须监视 ADO.NET 在其中创建和增加这些计数器的系统。如果您从远程系统进行连接,ADO.NET 并不总是在 Microsoft IIS 服务器或 SQL Server 上创建池;它在 ADO.NET 代码运行的系统上创建池。此系统可以是运行 IIS、Web 应用程序或 Web 服务的远程 Windows 或中间层系统。相反,SQL Server 性能计数器位于 SQL Server 系统上 — 而不是客户端上。
使用性能监视器来监视池。 如果您使用 Microsoft 管理控制台 (MMC) Windows 2000 系统监视器管理单元,则您可以通过从 Performance 对象下拉列表中选择 “.NET CLR Data” 来用图形表示 SqlClient 计数器,如 图 1所示。请注意,您可以通过选择 global 计数器实例来监视所有进程,或者,您可以查看某个特定实例 — 每个池生成自己的一组监视器。性能监视器可列出这些计数器,并将它们作为所选定的性能对象的实例提供。但性能监视器不会公开这些计数器,除非有实例需要它们进行监视。例如,图 1 显示了 .NET CLR Data 性能对象,但没有列出特定实例。这意味着您必须至少创建一个连接,以便使 global 实例连同每个进程的特定实例一起出现。这种行为对于您的代码来说是个问题;您将无法使用 PerformanceCounter 控件来返回其中的任何计数器,直到 ADO.NET 在打开连接时创建这些计数器。所以说,这个规定真有点令人左右为难。当您使用此方法时,因为缺少有效计数器实例,所以会引发异常 — 此时要准备好捕获异常。
您还可以通过使用 SQL Server 性能计数器 “User Connections” 来监视打开的连接的数量。该计数器被列在 Performance 对象下拉列表中的 SQL Server: General Statistics 下。我喜欢监视 “User Connections” 值和一些所选定的 .NET CLR Data SqlClient 计数器(我稍后将讨论此内容),因为我可以获得我需要的信息,而不必担心实例。
使用代码来监视性能计数器。 当您需要以编程方式监视连接池时,您可以编写代码来监视由 SqlClient 管理的性能计数器 — 这些计数器与 MMC Windows NT 性能监视器管理单元所提供的计数器是相同的。编写执行监视的代码似乎是一件有些令人畏惧的事情。但我已经提供了从 SqlClient 提供程序的内部工作提取这些计数器的例程的快照(作为本文提供的可下载程序之一)。
您可以编写检查 表 2显示的五个计数器的代码。通过利用这五个计数器,您可以实时监视连接池。.NET 预期您会在性能监视器中提供一个类别 — 复制的 Performance — 并从那些注册到系统的计数器中选择适当的计数器。要访问 SqlClient 计数器,请将该类别设置为 “.NET CLR Data”。
使用 PerformanceCounter 控件。 您可能会发现,在设计时向您的应用程序窗体添加 PerformanceCounter 要比手工编写代码来访问性能计数器更加容易。要使用 PerformanceCounter 控件,请从“Visual Studio .NET 工具箱组件”菜单中选择一个 PerformanceCounter,将它拖到您的应用程序窗体,然后设置属性,如 图 2 所示。这些控件工作在 Web 窗体和 WinForms 应用程序中。
因为 PerformanceCounter 控件提供了方便的下拉列表,所以,您可以在设计时看到任何一种性能计数器类别、计数器名称和特定实例 — 您将要运行的实例除外。这意味着您必须使用图 2 显示的方法来捕获应用程序正在使用的池的适当实例。为了回避这个问题,我选择 global 实例。再次说明一下,此方法假设某个应用程序已经至少创建了一个池,因此您需要做好不存在计数器实例时 ADO.NET 引发异常的准备,就像它在不存在池连接时也会引发异常一样。