Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置 SQL Timeout超时的处理方法

SQL Timeout超时的处理方法

 

第一步:修改Web.config配置文件。在数据库链接字符串中加上链接时间Connect Timeout,根据实际状况定时间。html

  1. <!--链接数据库-->  
  2. <connectionStrings>  
  3.      <add name="strConnDB" connectionString=" Data Source=192.168.*.*;Initial Catalog=DatabaseName;Persist Security Info=True;User id=sa;Password=password;pooling=true;max pool size=800;min pool size=300;<span style="color:#FF0000;">Connect Timeout=500</span>;"/>  
  4. </connectionStrings>  


第二步:修改command对象的CommandTimeout属性。 数据库

  1. SqlCommand cmd = new SqlCommand();  
  2. cmd.CommandTimeout = 180;  

这里设置的时间是180秒,即三分钟!可根据须要设置,若是过长,也能够设置为0,当此属性设置为0时表示不限制时间。此属性值应该慎用。

到此为止,问题完美解决。

补充:
SqlCommand.CommandTimeOut:获取或设置在终止执行命令的尝试并生成错误以前的等待时间。
SqlConnection.ConnectionTimeout:获取在尝试创建链接时终止尝试并生成错误以前所等待的时间。浏览器

 

 

 

参考数据库连接串:服务器

<add key="data" value="server=192.168.1.123; Port=3306; uid=root; pwd=root;database=data;pooling=true;min pool size=5;max pool size=512;connect timeout = 20; "/>  

 

查看应用程序池占用数量:post

select * from sysprocesses where dbid= db_id('数据库名')

 

 

Max Pool Size:若是未设置则默认为100,理论最大值为32767。最大链接数是链接池能申请的最大链接数,若是数据库链接请求超过此数,后面的数据库链接请求将被加入到等待队列中,这会影响以后的数据库操做。在等待队列中,默认等待与服务器的链接的时间为15秒。ui

 

中文错误:url

超时时间已到。超时时间已到,可是还没有从池中获取链接。出现这种状况多是由于全部池链接均在使用,而且达到了最大池大小。spa

英文错误:.net

Timeout expired.  The timeout period elapsed prior to obtaining a connection from the pool.  This may have occurred because all pooled connections were in use and max pool size was reached. code

问题描述:咱们获取链接超过链接池最大值时产生如上异常。一般链接池最大值为100。当咱们获取链接超过最大值时,ADO.NET等待链接池返回链接而超时,这样将抛出如上异常
解决办法:首先要作的是在咱们使用链接后当即关闭链接。若是没有关闭链接那么链接将保存到链接池中知道GC来销毁。这种状况下你觉得链接池没有到达最大值但实际上链接池已经到达了最大值 其次咱们能够经过链接字符串中的Max Pool Size = N;来动态扩大链接池中的链接最大数量。

说明: 

也就是在connectionString中若是未指定max pool size的值,则max pool size=100,当访问人员同时链接数据库的数量为101人时,则等待SqlConnection.ConnectionTimeout设置的时间(默认是15 秒)后,仍是没有可用的Connection则会出现上面的错误。

当咱们设置为:

"Server=(local); Integrated Security=SSPI; Database=Northwind; Max Pool Size=512; Min Pool Size=5"  时。则访问人员同时链接数据库的数量为513时,则等待SqlConnection.ConnectionTimeout设置的时间(默认是15 秒)后,仍是没有可用的Connection则 就会出现上面的错误。

 

 

-           Connection Pool  是什么呢 ?
每当程序须要读写数据库的时候。Connection.Open()会使用ConnectionString链接到数据库,数据库会为程序创建 一个链接,而且保持打开状态,此后程序就可使用T-SQL语句来查询/更新数据库。当执行到Connection.Close()后,数据库就会关闭当 前的链接。很好,一切看上去都是如此有条不紊。
 
可是若是个人程序须要不定时的打开和关闭链接,(好比说 ASP.Net 或是 Web Service ),例如当Http Request发送到服务器的时候、,咱们须要打开Connection 而后使用Select* from Table 返回一个DataTable/DataSet给客户端/浏览器,而后关闭当前的Connection。那每次都Open/Close Connection 如此的频繁操做对于整个系统无疑就成了一种浪费。
 
ADO.Net Team就给出了一个比较好地解决方法。将先前的Connection保存起来,当下一次须要打开链接的时候就将先前的Connection 交给下一个链接。这就是Connection Pool。


-           Connection Pool  如何工做的?
首先当一个程序执行Connection.open()时候,ADO.net就须要判断,此链接是否支持Connection Pool (Pooling 默认为True),若是指定为False, ADO.net就与数据库之间建立一个链接(为了不混淆,全部数据库中的链接,都使用”链接”描述),而后返回给程序。

若是指定为 True,ADO.net就会根据ConnectString建立一个Connection Pool,而后向Connection Pool中填充Connection(全部.net程序中的链接,都使用”Connection”描述)。填充多少个Connection由Min Pool Size (默认为0)属性来决定。例如若是指定为5,则ADO.net会一次与SQL数据库之间打开5个链接,而后将4个Connection,保存在 Connection Pool中,1个Connection返回给程序。

 
当程序执行到Connection.close() 的时候。若是Pooling 为True,ADO.net 就把当前的Connection放到Connection Pool而且保持与数据库之间的链接。

同时还会判断Connection Lifetime(默认为0)属性,0表明无限大,若是Connection存在的时间超过了Connection LifeTime,ADO.net就会关闭的Connection同时断开与数据库的链接,而不是从新保存到Connection Pool中。

(这个设置主要用于群集的SQL 数据库中,达到负载平衡的目的)。若是Pooling指定为False,则直接断开与数据库之间的链接。

 
而后当下一次Connection.Open() 执行的时候,ADO.Net就会判断新的ConnectionString与以前保存在Connection Pool中的Connection的connectionString是否一致。

(ADO.Net会将ConnectionString转成二进制流,所 以也就是说,新的ConnectionString与保存在Connection Pool中的Connection的ConnectionString必须彻底一致,即便多加了一个空格,或是修改了Connection String中某些属性的次序都会让ADO.Net认为这是一个新的链接,而重新建立一个新的链接。因此若是您使用的UserID,Password的认 证方式,修改了Password也会致使一个Connection,若是使用的是SQL的集成认证,就须要保存两个链接使用的是同一个)。

而后 ADO.net须要判断当前的Connection Pool中是否有可使用的Connection(没有被其余程序所占用),若是没有的话,ADO.net就须要判断ConnectionString设 置的Max Pool Size (默认为100),若是Connection Pool中的全部Connection没有达到Max Pool Size,ADO.net则会再次链接数据库,建立一个链接,而后将Connection返回给程序。

若是已经达到了 MaxPoolSize,ADO.net就不会再次建立任何新的链接,而是等待Connection Pool中被其余程序所占用的Connection释放,这个等待时间受SqlConnection.ConnectionTimeout(默认是15 秒)限制,也就是说若是时间超过了15秒,SqlConnection就会抛出超时错误(因此有时候若是SqlConnection.open()方法抛 出超时错误,一个可能的缘由就是没有及时将以前的Connnection关闭,同时Connection Pool数量达到了MaxPoolSize。)

若是有可用的Connection,从Connection Pool 取出的Connection也不是直接就返回给程序,ADO.net还须要检查ConnectionString的ConnectionReset属性 (默认为True)是否须要对Connection 最一次reset。这是因为,以前从程序中返回的Connection可能已经被修改过,好比说使用 SqlConnection.ChangeDatabase method 修改当前的链接,此时返回的Connection可能就已经不是链接当前的Connection String指定的Initial Catalog数据库了。因此须要reset一次当前的链接。可是因为全部的额外检查都会增大ADO.net Connection Pool 对系统的开销。

相关文章
相关标签/搜索