C#数据库连接池介绍(转自MSDN)

 

使用连接池

连接到数据库服务器通常由几个需要很长时间的步骤组成。必须建立物理通道(例如套接字或命名管道),必须与服务器进行初次握手,必须分析连接字符串信息,必须由服务器对连接进行身份验证,必须运行检查以便在当前事务中登记,等等。

实际上,大多数应用程序仅使用一个或几个不同的连接配置。这意味着在执行应用程序期间,许多相同的连接将反复地打开和关闭。为了使打开的连接成本最低,ADO.NET 使用称为连接池的优化方法。

连接池减少新连接需要打开的次数。池进程保持物理连接的所有权。通过为每个给定的连接配置保留一组活动连接来管理连接。只要用户在连接上调用 Open,池进程就会检查池中是否有可用的连接。如果某个池连接可用,会将该连接返回给调用者,而不是打开新连接。应用程序在该连接上调用 Close 时,池进程会将连接返回到活动连接池集中,而不是真正关闭连接。连接返回到池中之后,即可在下一个 Open 调用中重复使用。

只有配置相同的连接可以建立池连接。ADO.NET 同时保留多个池,每个配置一个池。连接由连接字符串以及 Windows 标识(在使用集成的安全性时)分为多个池。

池连接可以大大提高应用程序的性能和可缩放性。默认情况下,ADO.NET 中启用连接池。除非显式禁用,否则,连接在应用程序中打开和关闭时,池进程将对连接进行优化。还可以提供几个连接字符串修饰符来控制连接池的行为。

池的创建和分配

在初次打开连接时,将根据完全匹配算法创建连接池,该算法将池与连接中的连接字符串关联。每个连接池与不同的连接字符串关联。打开新连接时,如果连接字符串并非与现有池完全匹配,将创建一个新池。按进程、按应用程序域、按连接字符串以及(在使用集成的安全性时)按 Windows 标识来建立池连接。

在以下 C# 示例中创建了三个新的 SqlConnection 对象,但是管理时只需要两个连接池。注意,根据为 Initial Catalog 分配的值,第一个和第二个连接字符串有所不同。

using (SqlConnection connection = new SqlConnection(

"Integrated Security=SSPI;Initial Catalog=Northwind"))

    {

        connection.Open();     

        // Pool A is created.

    }

using (SqlConnection connection = new SqlConnection(

"Integrated Security=SSPI;Initial Catalog=pubs"))

    {

        connection.Open();     

        // Pool B is created because the connection strings differ.

    }

using (SqlConnection connection = new SqlConnection(

"Integrated Security=SSPI;Initial Catalog=Northwind"))

    {

        connection.Open();     

        // The connection string matches pool A.

    }

如果 MinPoolSize 在连接字符串中未指定或指定为零,池中的连接将在一段时间不活动后关闭。但是,如果指定的 MinPoolSize 大于零,在 AppDomain 被卸载并且进程结束之前,连接池不会被破坏。非活动或空池的维护只需要最少的系统开销。

添加连接

连接池是为每个唯一的连接字符串创建的。当创建一个池后,将创建多个连接对象并将其添加到该池中,以满足最小池大小的要求。连接根据需要添加到池中,但是不能超过指定的最大池大小(默认值为 100)。连接在关闭或断开时释放回池中。

在请求 SqlConnection 对象时,如果存在可用的连接,将从池中获取该对象。连接要可用,必须未使用,具有匹配的事务上下文或未与任何事务上下文关联,并且具有与服务器的有效链接。

连接池进程通过在连接释放回池中时重新分配连接,来满足这些连接请求。如果已达到最大池大小且不存在可用的连接,则该请求将会排队。然后,池进程尝试重新建立任何连接,直到到达超时时间(默认值为 15 秒)。如果池进程在连接超时之前无法满足请求,将引发异常。

们建议您在使用完连接时一定要关闭连接,以便连接可以返回池。要关闭连接,可以使用 Connection 对象的 Close 或 Dispose 方法,也可以通过在 C# 的 using 语句中或在 Visual Basic 的 Using 语句中打开所有连接。不是显式关闭的连接可能不会添加或返回到池中。例如,如果连接已超出范围但没有显式关闭,则仅当达到最大池大小而该连接仍然有效时,该连接才会返回到连接池中。有关更多信息,请参见 Visual Basic 的using 语句(C# 参考)如何:释放系统资源

注意

 

不要在类的 Finalize 方法中对 Connection、DataReader 或任何其他托管对象调用 Close 或 Dispose。在终结器中,仅释放类直接拥有的非托管资源。如果类不拥有任何非托管资源,则不要在类定义中包含 Finalize 方法。有关更多信息,请参见垃圾回收

移除连接

连接池进程定期扫描连接池,查找没有通过 Close 或 Dispose 关闭的未用连接,并重新建立找到的连接。如果应用程序没有显式关闭或断开其连接,连接池进程可能需要很长时间才能重新建立连接,所以,最好确保在连接中显式调用 Close 和 Dispose。

如果连接长时间空闲,或池进程检测到与服务器的连接已断开,连接池进程会将该连接从池中移除。注意,只有在尝试与服务器进行通信之后才能检测到断开的连接。如果发现某连接不再连接到服务器,则会将其标记为无效。无效连接只有在关闭或重新建立后,才会从连接池中移除。

如果存在与已消失的服务器的连接,那么即使连接池管理程序未检测到已断开的连接并将其标记为无效,仍有可能将此连接从池中取出。这种情况是因为检查连接是否仍有效的系统开销将造成与服务器的另一次往返,从而抵消了池进程的优势。发生此情况时,初次尝试使用该连接将检测连接是否曾断开,并引发异常。

清除池

ADO.NET 2.0 引入了两种新的方法来清除池:ClearAllPoolsClearPool。ClearAllPools 清除给定提供程序的连接池,ClearPool 清除与特定连接关联的连接池。如果在调用时连接正在使用,将进行相应的标记。连接关闭时,将被丢弃,而不是返回池中。

posted on 2010-08-18 21:42  black263  阅读(652)  评论(0编辑  收藏  举报