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

实际上,大多数应用程序仅运用一个或几个不同的衔接装备。 这意味着在履行应用程序期间,许多相同的衔接将重复地翻开和封闭。 为了使翻开的衔接本钱***,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:     {
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))0
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))1
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))2
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))3
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))4
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))5
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))6
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))7
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))8
   2:   "Integrated Security=SSPI;Initial Catalog=Northwind"))9

假如 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;

经过上面的两篇文章期望我们能够理解什么是数据库衔接池,什么时候适用,什么时候不适用。关于功能测验,我做了一个小比如,我们能够看看:

***次运转:

ADO.NET中SQL Server数据库连接池(ado技术连接sqlserver数据库)  ADO.NET 第1张

屡次运转后:

ADO.NET中SQL Server数据库连接池(ado技术连接sqlserver数据库)  ADO.NET 第2张

测验按钮的代码如下:

   3:     {0
   3:     {1
   3:     {2
   3:     {3
   3:     {4
   3:     {5
   7: 
   3:     {7
   3:     {8
   3:     {9
   4:         connection.Open();      0
转载请说明出处
知优网 » ADO.NET中SQL Server数据库连接池(ado技术连接sqlserver数据库)

发表评论

您需要后才能发表评论