`

ADO.NET中SQL Server数据库连接池

 
阅读更多

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

AD:

 

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

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

只有配置相同的连接可以建立池连接。 ADO.NET 同时保留多个池,每个配置一个池。 连接由连接字符串以及 Windows 标识(在使用集成的安全性时)分为多个池。 还根据连接是否已在事务中登记来建立池连接。

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


池的创建和分配

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

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

 

   1: using (SqlConnection connection = new SqlConnection(
2: "Integrated Security=SSPI;Initial Catalog=Northwind"))
   3:     {
   4:         connection.Open();      
   5:         // Pool A is created.
   6:     }
   7:  
   8: using (SqlConnection connection = new SqlConnection(
   9:   "Integrated Security=SSPI;Initial Catalog=pubs"))
  10:     {
  11:         connection.Open();      
  12:         // Pool B is created because the connection strings differ.
  13:     }
  14:  
  15: using (SqlConnection connection = new SqlConnection(
  16:   "Integrated Security=SSPI;Initial Catalog=Northwind"))
  17:     {
  18:         connection.Open();      
  19:         // The connection string matches pool A.
  20:     }

 

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

注意:

当出现故障转移等错误时,会自动清除池。

添加连接

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

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

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

警告:
我们强烈建议您在使用完连接后总是将其关闭,以使连接返回到池中。要关闭连接,可以使用 Connection 对象的 CloseDispose 方法,也可以通过在 C# 的 using 语句中或在 Visual Basic 的 Using 语句中打开所有连接。 不是显式关闭的连接可能不会添加或返回到池中。

移除连接

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

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

清除池

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

使用连接字符串关键字控制连接池

下表列出了 ConnectionString 内连接池值的有效名称。有关更多信息,请参见 SQL Server 连接池 (ADO.NET)。

Connection Lifetime

0

当连接被返回到池时,将其创建时间与当前时间作比较,如果时间长度(以秒为单位)超出了由 Connection Lifetime 指定的值,该连接就会被销毁。这在聚集配置中很有用(用于强制执行运行中的服务器和刚置于联机状态的服务器之间的负载平衡)。

零 (0) 值将使池连接具有最大的连接超时。

Connection Reset

'true'

确定从池中提取数据库连接时是否重置数据库连接。对于 SQL Server 7.0 版,设置为 false 可避免获取连接时再有一次额外的服务器往返行程,但须注意此时并未重置连接状态(如数据库上下文)。

只要不将 Connection Reset 设置为 false,连接池程序就不会受到 ChangeDatabase 方法的影响。连接在退出相应的连接池以后将被重置,并且服务器将移回登录时数据库。不会创建新的连接,也不会重新进行身份验证。如果将 Connection Reset 设置为 false,则池中可能会产生不同数据库的连接。

Enlist

'true'

当该值为 true 时,池程序在创建线程的当前事务上下文中自动登记连接。可识别的值为 true、false、yes 和 no。

Load Balance Timeout

0

连接被销毁前在连接池中生存的最短时间(以秒为单位)。

Max Pool Size

100

池中允许的最大连接数。

Min Pool Size

0

池中允许的最小连接数。

Pooling

'true'

当该值为 true 时,系统将从适当的池中提取 SQLConnection 对象,或在需要时创建该对象并将其添加到适当的池中。可识别的值为 true、false、yes 和 no。

 

 

 

从深蓝居的博客上找到的描述:

前几天同事问我一个问题,一种CS架构的程序,直接把SQL Server作为服务端,每个客户端直接连接数据库操作(kay注:S2的cs项目就是这种架构),如果客户端打开的数量过多时SQL Server的连接数将会特别高,数据库端形成性能瓶颈,这种情况下怎么办?想了想,造成这种情况的原因是ADO.NET的内部机制造成的。ADO.NET中为了提高性能,所以使用了连接池,这样每个请求就不必都创建一个连接,然后认证,然后执行SQL,而是从连接池中直接取出连接执行SQL,执行完成后也并不是真正关闭连接,而是将该连接重新放回连接池中。如果有100个客户端,每个客户端在使用一段时间后连接池中保存了10个连接,那么在这种情况下,即使不在客户端做任何操作,SQL Server上都有1000个连接,这样不出性能问题才怪。

既然是连接池的问题,那么我就针对该问题想到了2个解决办法:

1.关闭ADO.NET的连接池,每次执行SQL时都是新建一个连接执行,然后关闭。这样做将使数据查询有所减慢(每次都建立连接,每次都认证,当然会慢了),不过这个慢是毫秒级的,一般感觉不到的,但是如果一个操作就涉及到几百个SQL语句的情况可能会明细感觉到减慢。修改方法特别简单,都不用修改代码,在数据库链接字符串中加入Pooling=False;即可。

2.修改架构,这种CS架构除了性能问题外还会出现其他的比如安全上的问题。可以将直接连数据库的方法改成连接服务,这其中可以使用Remoting、Web服务等,当然现在可以统一用WCF了。这样做就只有服务程序去连接数据库,而客户端只连接服务程序,这样就不会出现连接池造成的瓶颈。不过这样做代码修改量很大,若真要改还是很痛苦的。

以下是网上找到的一篇介绍ADO.NET连接池的文章,感觉不错。

连接池允许应用程序从连接池中获得一个连接并使用这个连接,而不需要为每一个连接请求重新建立一个连接。一旦一个新的连接被创建并且放置在连接池中,应用程序就可以重复使用这个连接而不必实施整个数据库连接创建过程。

当应用程序请求一个连接时,连接池为该应用程序分配一个连接而不是重新建立一个连接;当应用程序使用完连接后,该连接被归还给连接池而不是直接释放。

如何实现连接池

确保你每一次的连接使用相同的连接字符串(和连接池相同);只有连接字符串相同时连接池才会工作。如果连接字符串不相同,应用程序就不会使用连接池而是创建一个新的连接。

优点

使用连接池的最主要的优点是性能。创建一个新的数据库连接所耗费的时间主要取决于网络的速度以及应用程序和数据库服务器的(网络)距离,而且这个过程通常是一个很耗时的过程。而采用数据库连接池后,数据库连接请求可以直接通过连接池满足而不需要为该请求重新连接、认证到数据库服务器,这样就节省了时间。

缺点

数据库连接池中可能存在着多个没有被使用的连接一直连接着数据库(这意味着资源的浪费)。

技巧和提示

1. 当你需要数据库连接时才去创建连接池,而不是提前建立。一旦你使用完连接立即关闭它,不要等到垃圾收集器来处理它。

2. 在关闭数据库连接前确保关闭了所有用户定义的事务。

3. 不要关闭数据库中所有的连接,至少保证连接池中有一个连接可用。如果内存和其他资源是你必须首先考虑的问题,可以关闭所有的连接,然后在下一个请求到来时创建连接池。

连接池FAQ

1. 何时创建连接池?

当第一个连接请求到来时创建连接池;连接池的建立由数据库连接的连接字符创来决定。每一个连接池都与一个不同的连接字符串相关。当一个新的连接请求到来时如果连接字符串和连接池使用的字符串相同,就从连接池取出一个连接;如果不相同,就新建一个连接池。

2. 何时关闭连接池?

当连接池中的所有连接都已经关闭时关闭连接池。

3. 当连接池中的连接都已经用完,而有新的连接请求到来时会发生什么?

当连接池已经达到它的最大连接数目时,有新的连接请求到来时,新的连接请求将放置到连接队列中。当有连接释放给连接池时,连接池将新释放的连接分配给在队列中排队的连接请求。你可以调用close和dispose将连接归还给连接池。

4. 我应该如何允许连接池?

对于.NET应用程序而言,默认为允许连接池。(这意味着你可以不必为这件事情做任何的事情)当然,如果你可以在SQLConnection对象的连接字符串中加进Pooling=true;确保你的应用程序允许连接池的使用。

5. 我应该如何禁止连接池?

ADO.NET默认为允许数据库连接池,如果你希望禁止连接池,可以使用如下的方式:

1) 使用SQLConnection对象时,往连接字符串加入如下内容:Pooling=False;

2) 使用OLEDBConnection对象时,往连接字符串加入如下内容:OLE DB Services=-4;

通过上面的两篇文章希望大家可以明白什么是数据库连接池,什么时候适用,什么时候不适用。关于性能测试,我做了一个小例子,大家可以看看:

第一次运行:

第一次运行

 

多次运行后:

多次运行后

 

测试按钮的代码如下:

 

 

 

   1: string connStringUsePool = "server=.;database=pubs;uid=sa;pwd=123456;pooling=true;connection lifetime=0;min pool size = 1;max pool size=50";
   2: string connStringUnUsePool = "server=.;database=pubs;uid=sa;pwd=123456;pooling=false";
   3:  
   4: private void button1_Click(object sender, EventArgs e)
   5: {
   6:     
   7:  
   8:     int count = 50;
   9:  
  10:     DateTime start = DateTime.Now;
  11:     for (int i = 0; i < count; i++)
  12:     {
  13:         using (SqlConnection conn = new SqlConnection(connStringUsePool))
  14:         {
  15:             conn.Open();
  16:             conn.Close();
  17:         }
  18:     }
  19:     DateTime end = DateTime.Now;
  20:     TimeSpan ts = end - start;
  21:     label1.Text = "使用连接池"+ts.Milliseconds.ToString();
  22:  
  23:     start = DateTime.Now;
  24:     for (int i = 0; i < count; i++)
  25:     {
  26:         using (SqlConnection conn = new SqlConnection(connStringUnUsePool))
  27:         {
  28:             conn.Open();
  29:             conn.Close();
  30:         }
  31:     }
  32:     end = DateTime.Now;
  33:     ts = end - start;
  34:     label2.Text = "不使用连接池" + ts.Milliseconds.ToString();
  35: }

 

【编辑推荐】

  1. ADO.NET中的多数据表操作读取
  2. 浅谈ADO.NET中的五个主要对象
  3. 使用LINQ和ADO.NET创建Silverlight程序
  4. ADO.NET数据库连接、操作SQL举例
  5. ADO.NET中容易混淆的概念
  • 大小: 24 KB
  • 大小: 29.2 KB
分享到:
评论

相关推荐

    ADO.NET中SQLServer数据库连接池

    为了使打开的连接成本最低,ADO.NET使用称为连接池的优化方法。连接池减少新连接需要打开的次数。池进程保持物理连接的所有权。通过为每个给定的连接配置保留一组活动连接来管理连接。只要用户在连接上调用Open,池...

    ado.net实现对sqlServer数据库的操作.docx

    在本文档中,我们使用的是 SqlConnection 类,它是 ADO.NET 中用于连接 SQL Server 数据库的类。 在连接数据库成功后,可以使用 SqlCommand 对象来执行 SQL 语句。SqlCommand 对象有两个主要的方法:...

    ADO.NET连接SQL Server

    - **连接池管理**:ADO.NET 支持连接池管理,可以在应用程序启动时初始化连接池,减少连接建立和断开的时间消耗。 - **使用参数化查询**:避免 SQL 注入攻击,提高安全性。 - **优化查询**:对复杂查询进行性能优化...

    ADO.NET访问SQL Server数据库技术的研究.pdf

    在本文中,我们将深入探讨ADO.NET如何实现对SQL Server数据库的访问,以及其关键组件和技术。 1. **ADO.NET架构** ADO.NET由几个主要组件组成:DataSet、DataTable、DataAdapter、Connection、Command、DataReader...

    SQL Server数据库连接池及jdbc调用

    本文将深入探讨SQL Server数据库连接池以及Java JDBC(Java Database Connectivity)如何进行调用。 首先,我们来理解什么是数据库连接池。数据库连接池是一种在应用服务器启动时预先建立的数据库连接集合,这些...

    C++使用ADO连接SQL Server数据库源代码

    - 数据库连接池:在大型应用中,可以考虑使用数据库连接池来管理连接,提高性能和效率。 通过深入理解以上知识点,并结合"ConnDatabase"源代码进行实践,初学者可以逐步掌握C++通过ADO连接SQL Server数据库的方法...

    asp.net(C#)sql server数据库ado.net操作类SqlServerHelper

    首先,`SqlConnection`是ADO.NET中用于连接SQL Server数据库的主要类。你需要提供正确的连接字符串,包括服务器名、数据库名、用户名和密码,以建立到数据库的连接。例如: ```csharp string connectionString = ...

    .net C# sqlserver数据库经典

    同时,C#的ADO.NET组件是连接SQLServer数据库的重要桥梁,它包括DataSet、DataTable、DataAdapter等对象,用于数据的检索、操作和持久化。 SQLServer数据库是Microsoft推出的企业级关系型数据库管理系统,具备高...

    Ado.Net数据库连接字符串大全

    2. 为确保最佳性能,应使用连接池,这是Ado.Net默认开启的功能,可重用已打开的连接,减少资源开销。 3. 记得在操作完数据库后关闭连接,以释放系统资源。 了解并正确使用Ado.Net的数据库连接字符串是开发.NET...

    浅谈使用ADO.NET和ASP.NET访问SQL Server数据库.pdf

    由于提供的【部分内容】中大部分内容均为乱码,无法从中提取出有意义的IT知识点,但是根据标题“浅谈使用***和***访问SQL Server数据库.pdf”和【描述】中的重复标题,我们可以推断出本文档的主要内容。以下将围绕**...

    深入ADO.NET开发-高级数据访问技术视频教程(C# ASP.NET SQL SERVER)

    ADO.NET是微软.NET框架中的一个核心组件,它提供了与各种数据源(如SQL Server)交互的能力。本教程首先会介绍ADO.NET的基本架构,包括Connection、Command、DataReader和DataAdapter等核心对象,以及它们在数据库...

    ASP.NET对SQL SERVER数据库的访问

    首先,要在ASP.NET中连接到SQL Server数据库,我们需要使用ADO.NET(ActiveX Data Objects .NET)组件。ADO.NET提供了一组数据访问接口,包括SqlConnection对象用于建立与SQL Server的连接,SqlCommand对象用于执行...

    ADO.net数据库连接示例程序

    在本示例程序中,我们将探讨如何利用ADO.NET进行数据库连接,包括使用Connection对象、Command对象、DataReader和DataAdapter等核心组件。 1. **Connection对象**:它是ADO.NET中与数据库建立连接的核心组件。通过...

    ADO.Net数据库访问(代码示例)

    在实际应用中,为了提高性能和减少资源消耗,通常会使用连接池来管理和复用数据库连接。此外,事务管理也是重要的一环,确保一组操作的原子性和一致性。 在使用ADO.NET时,还需要注意以下几点: - 错误处理:确保...

    ADO.NET数据库实例

    通过上述步骤,你可以使用ADO.NET有效地与SQL Server数据库进行交互。"数据库基本操作.exe"可能是实现这些操作的可执行程序,而"运行前必读.txt"可能包含了运行程序前的注意事项和步骤说明。"数据库基本操作"可能是...

    .NET数据库连接测试

    通过以上内容,您可以理解.NET中SQL Server数据库连接测试的基本概念和实现方式。在实际项目中,根据需求,可能还需要考虑错误处理、性能优化、多线程安全等问题。在进行数据库连接测试时,确保所有操作都能正常运行...

    ADO.NET与SQL数据库的连接与访问研究.pdf

    通过对这些知识点的学习,开发者能够更好地理解和掌握如何在.NET环境下实现数据库连接和数据访问操作。 总的来说,***与SQL数据库的连接与访问技术是开发者在创建各种Web应用程序时不可或缺的技能。掌握这些技术...

    ADO.Net详解,Net数据库操作,Vb.Net数据库编程

    - **1.2.1 使用SqlClient创建基本ADO.NET数据对象**:通过使用`SqlClient`命名空间中的类,可以轻松地与SQL Server数据库进行交互。 - **1.2.2 对多表更新应用事务**:事务处理是保证数据一致性的关键,ADO.NET支持...

    ADO.NET数据库访问技术案例教程

    ADO.NET使用连接池来管理数据库连接,减少创建和销毁连接的开销,提高系统性能。开发者还可以通过设置ConnectionString中的属性进行进一步的性能优化。 八、案例分析 在实际开发中,通常会结合ASP.NET或Windows ...

Global site tag (gtag.js) - Google Analytics