您的位置:首页 > 编程语言 > ASP

asp.net连接数据库超时的解决办法

2017-08-25 22:32 281 查看
错误提示:“超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。”

经过几天辛苦写的代码,终于实现了功能丰富的查询功能,但是使用的过程中,却经常出现上面的错误,百思不得其解。写代码的时候就担心因为功能复杂,效率会很低。

解决方案一

我想原因可能是并发操作。DataReader是独占连接的,就是说你的程序可能设计上有问题。比如说最大连接设100,假设有100个人同时使用DataReader正在读取数据库内容,那么当第101人读取的时候,连接池中的连接已经没有了,就会出现上面的错误。DataReader是独占连接的,每个DataReader都要占用一个连接。当然这个情况是偶尔出现的,所以会很长时间出现一次,因为只有同时有超过连接池最大连接数量的并发操作才会发生。而且你加大并发数量只能暂时缓解问题,如果你加大到200个并发连接,如果有201人同时操作怎么办?你说了你使用Connection对象的Close()方法,这是不行的,因为Close()方法仅仅是关闭连接,但这个连接没有释放,还是被这个对象占用,要释放必须使用Connection的Dispose()方法显式释放连接才可以,否则这个对象占用的连接只能等到垃圾收集的情况下才能被释放。这种情况肯定会出现“超时时间已到”的错误。

解决方法:

1修改几个关键页面或访问比较频繁的数据库访问操作,使用DataAdapter和DataSet来获取数据库数据,不要使用DataReader。

2在访问数据库的页面上使用数据缓存,如果页面的数据不是经常更新(几分钟更新一次)的话,使用Cache对象可以不用访问数据库而使用缓存中的内容,那么可以大大减少连接数量。

3修改代码,把使用Connection对象的地方都在Close()后面加上Dispose()调用。

4建议对数据库操作进行大的修改,建立自己的数据库操作代理类,继承System.IDisposable接口,强迫释放资源,这样就不会出现连接数量不够的问题了。

解决方案二

解决方法(*):WEB.config里面:在数据库连接加MaxPoolSize=512;server=local;uid=;pwd=;database=2004;MaxPoolSize=512;">一劳永逸。

解决方案三

估计是连接(Connection)对象没有Close。倒是不必Dispose,而DataReader用完后应该关闭,但不关闭也没问题,只是不关闭的话此连接对象就一直不能用,只要你最终关闭了连接对象就不会出问题。

连接对象在Open后的操作都放在try块中,后面跟一个finally块:conn.Close();

:errorconnecting:Timeoutexpired.Thetimeoutperiodelapsedprior
toobtainingaconnectionfromthepool.Thismayhaveoccurredbecause
allpooledconnectionswereinuseandmaxpoolsizewasreached

超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。

问题描述:我们获取连接超过连接池最大值时产生如上异常。通常连接池最大值为100。当我们获取连接超过最大值时,ADO.NET等待连接池返回连接而超时,这样将抛出如上异常

产生这样的问题:连接数大于N并且超出设置的时间(所有连接池中的连接都在用,并且等待的时间超时)
解决办法:1首先要做的是在我们使用连接后立即关闭连接

2其次我们可以通过连接字符串中的MaxPoolSize=N;来动态扩大连接池中的连接最大数量。

3更改连接时间connecttimeout=N


首先要保证所有的connection连接之后都要手动的关闭,特别是DataReader(


一个connection对象只能打开一个DataReader对象,在该datareader对象关闭之前,无法打开其他的datareader对象,知道该datareader对象调用close方法为止)

更改连接数量和连接时间根据实际情况而定

为什么会出现这样的问题呢?

就是比如买票一样,五个窗口同时创建,每个人都有自己的等待时间.假如五个创建,占用一个.还有四个空闲.占用五个.剩下的人需要等待.但是可能等待的时间很长.这些人都会不耐烦(超出规定时间)的走了.出现异常


正规的解释

-ConnectionPool如何工作的?(摘抄自(http://www.cnblogs.com/qqflying/archive/2012/02/13/2349583.html))

首先当一个程序执行Connection.open()时候,ADO.net就需要判断,此连接是否支持ConnectionPool(Pooling默认为True),如果指定为False,ADO.net就与数据库之间创建一个连接(为了避免混淆,所有数据库中的连接,都使用”连接”描述),然后返回给程序。

如果指定为True,ADO.net就会根据ConnectString创建一个ConnectionPool,然后向ConnectionPool中填充Connection(所有.net程序中的连接,都使用”Connection”描述)。填充多少个Connection由MinPoolSize(默认为0)属性来决定。例如如果指定为5,则ADO.net会一次与SQL数据库之间打开5个连接,然后将4个Connection,保存在ConnectionPool中,1个Connection返回给程序。

当程序执行到Connection.close()的时候。如果Pooling为True,ADO.net就把当前的Connection放到ConnectionPool并且保持与数据库之间的连接。

同时还会判断ConnectionLifetime(默认为0)属性,0代表无限大,如果Connection存在的时间超过了ConnectionLifeTime,ADO.net就会关闭的Connection同时断开与数据库的连接,而不是重新保存到ConnectionPool中。

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

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

(ADO.Net会将ConnectionString转成二进制流,所以也就是说,新的ConnectionString与保存在ConnectionPool中的Connection的ConnectionString必须完全一致,即使多加了一个空格,或是修改了ConnectionString中某些属性的次序都会让ADO.Net认为这是一个新的连接,而从新创建一个新的连接。所以如果您使用的UserID,Password的认证方式,修改了Password也会导致一个Connection,如果使用的是SQL的集成认证,就需要保存两个连接使用的是同一个)。

然后ADO.net需要判断当前的ConnectionPool中是否有可以使用的Connection(没有被其他程序所占用),如果没有的话,ADO.net就需要判断ConnectionString设置的MaxPoolSize(默认为100),如果ConnectionPool中的所有Connection没有达到MaxPoolSize,ADO.net则会再次连接数据库,创建一个连接,然后将Connection返回给程序。

如果已经达到了MaxPoolSize,ADO.net就不会再次创建任何新的连接,而是等待ConnectionPool中被其他程序所占用的Connection释放,这个等待时间受SqlConnection.ConnectionTimeout(默认是15秒)限制,也就是说如果时间超过了15秒,SqlConnection就会抛出超时错误(所以有时候如果SqlConnection.open()方法抛出超时错误,一个可能的原因就是没有及时将之前的Connnection关闭,同时ConnectionPool数量达到了MaxPoolSize。)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐
章节导航