解决一个问题的思路 之“解决已经写满con.close() 仍然出现"但是尚未从池中获取连接"的连接池耗尽问题”

来cnblogs快一年了,斗胆发一篇在首页,

这篇文章主要写解决一个网上答案不能解决自己问题的时候,解决问题的整个流程,

如果大家觉得这个没价值,还请管理员帮忙撤销发首页

先谢谢各位了。

 

一年前帮学校做了一个就业信息管理系统,

当时图热闹,觉得虽然说学校人不是很多,但是看惯了大家对GridView的性能的漫骂,

抱着练手的想法,自己用repeater 代替了GridView 来做数据显示

之后系统采用三层架构设计。。。。

之后做好了在自己本机上怎么测都没毛病,觉得差不多了

就向学校申请服务器架设,

结果没用几天,出毛病了,  老是提示

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

ok,google 了下,这个一般是因为DbConnection 开启了之后忘记关闭的(参见http://www.cnblogs.com/peak/archive/2009/04/24/1443116.html

自己本身写了个DbHelper,改起来应该很快,

结果一看,雷到了,原来我在DbHelper里面已经关闭了啊

 

Code

 

百思不得其解,最后没办法,临时想了个方案,关闭“连接池”

在web.config 中写入

 connectionString="Data Source=.\sqlexpress;Initial Catalog=YTJY;User ID=xxx;Password=xxx;pooling=false"

懂行的一看就知道是笨办法。。。

用了一段时间,貌似不报那个错了,所以就没注意了

可是,

今年6月,这个错误又华丽的出现了。

原来跑就业那台服务器因为项目需要,又装了个Oracle

额,抱歉,我一直说服务器,实际上是台pc机,联想的,配置忘记了,就记得是512 的内存后来换成1G的了,07年买的菠萝机

内存直接常年1G 占满

最后没办法,学校传说去采购了9k 的服务器(真的服务器了)

虽然马上就华丽的本科毕业(还几天就答辩。。。)

但是如果程序放新的服务器上还是不得行,校方直接毕业设计挂我我不是惨死。。。。。

没办法,琢磨着解决问题吧。。。

研究错误提示

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

反复读这句话,连接池我已经取消了啊,相当于每次读数据都是从数据库里申请链接,没有连接池的概念了哈

终于,发现一个很抑郁的事情

我理解这句话理解错了,或者,微软没描述好这句话的意思。

这个错误提示的核心应该是超时时间已到

而不是“尚未从池中获取连接

引起这个错误的原因只是数据库连接超时了,微软关于为什么超时的解释是“尚未从池中获取连接”,但是问题的本质,还是连接数据库超时

回想下大二学的数据库的知识,貌似数据库超时主要原因有

1、死锁

2、申请的链接数过多导致数据库来不及响应

3、网络连接错误。。。

 

我第一个排除的就是死锁,因为在出错的操作里面,没有设计到任何关于“增删改”的操作,没有失误的参与,仅仅是简单的Select,应该不可能出现死锁

第二个排除的是链接错误,因为IIS和SQLServer存在一台机器上,应该不会。。。

由此,估计是申请的连接数过多而导致了 数据库超时,

ok,现在的目标就是,检测系统到底打开了多少个数据库连接。

ok,由于是通宵作战,不在实验室,就跑的本机,

机器撇,就装了个Express 版本的SQLServer 2005

没有自带的工具

只好网上google  了下,发现了个不错的监视软件,free。。。。

叫SqlExpressProfiler....   http://code.google.com/p/sqlexpressprofiler/

用来监视数据库打开的链接,

小小的配置一下

 

因为我需要知道执行了多少条记录,于是打开AuditLogin 选项(因为每次执行都要数据库登录下。。。。)

 

 

加断点跑跑

不跑不知道,一跑吓一跳。。。。。

这是我打开一个页面的记录。。。。

页面为

建立的数据链接为

看一下右面的滚动条就知道了。。。。链接数据库50次左右。。。。

ok,问题顿时就明朗了。

打开一个页面访问数据库上50次,

如果有一个老师跑来审核数据,之后没事点“下一页”

短时间内,可以打开超过200个数据库连接

之后这几天刚好是教委填报数据的时候,

几乎所有辅导员都在审核这些信息,

假设有5个辅导员同时看这些资料,

那么短时间内,就有1000次链接数据库。。。。。。

我的妈呀。。。。让菠萝机上1000次,连的上数据库才怪。

ok,知道问题所在了,下面就非常容易了

加断点,单步走,每走一步看下数据库连接数

没过几分钟,就查到了问题所在,

问题来自于绑定分页的地方。。

我不知道那根经不对,写了这样一个语句。。。。。。。

Code

 

想必大家一眼就看到了这个错误,

for语句中   判断是每循环一次都要执行的,然而我在判断i 的时候竟然将判断条件写成了调用“逻辑业务层”,逻辑业务层调用数据链路层,

这样直接导致了循环有多少次,就查了多少次数据库。。。。。。

 

将这个地方更正,连接数立马下降到5个以内。。。。

至此,遗留了1年的bug,就此解决。。。。。。

 

ok,总结下吧。

---------------------------------------------------

第一,要相信科学。当出现那个“超时时间已到”的提示,之后google后按照方法做,还是不行的时候,要坚信,这是会解决的。

第二,临时方法靠不住。临时方法临时解决问题,只有找到处问题的根源,才能真正的解决问题。

第三,for语句中的判断条件,一定要慎重,再慎重,除非确定必要,否则坚决不在此使用任何函数,特别是可能操作数据库的函数

---------------------------------------------------

 

 

恩恩,写完了,希望本文能给您带来一些收获,

再次感谢您看完这篇文章,也希望多多与大家交流,

第一次发在首页,压力很大,但是真的很想与大家分享这次经验

如果不适合放首页,麻烦管理员撤下,谢谢了

 

 

 

 

posted @ 2009-06-07 07:13  Atpking  阅读(4672)  评论(27编辑  收藏  举报