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

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

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

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

先谢谢各位了。

 

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

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

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

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

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

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

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

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

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

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

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

 

ContractedBlock.gif ExpandedBlockStart.gif Code
        /// <summary>
        
/// 执行查询语句,返回DataSet
        
/// </summary>
        
/// <param name="SQLString">查询语句</param>
        
/// <returns>DataSet</returns>
        public static DataSet Query(string SQLString)
        {
            
using (SqlConnection connection = new SqlConnection(connectionString))
            {
                DataSet ds 
= new DataSet();
                
try
                {
                    connection.Open();
                    SqlDataAdapter command 
= new SqlDataAdapter(SQLString, connection);
                    command.Fill(ds, 
"ds");
                }
                
catch (System.Data.SqlClient.SqlException ex)
                {
                    
throw new Exception(ex.Message);
                }
                
finally
                {
                    connection.Close();
                }
                
return ds;
            }
        }

 

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

在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,知道问题所在了,下面就非常容易了

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

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

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

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

ContractedBlock.gif ExpandedBlockStart.gif Code
            
            
for (int i = 0; i < Bll_JiuyeList.getPageCount(PAGESIZE, getStrWhere()); i++)
            {
                DropDownList_Jump.Items.Add((i 
+ 1).ToString());
            }
            DropDownList_Jump.SelectedValue 
= "1";

 

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

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

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

 

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

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

 

ok,总结下吧。

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

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

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

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

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

 

 

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

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

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

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

 

 

 

 

转载于:https://www.cnblogs.com/jicheng1014/archive/2009/06/07/1497919.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值