1.问题的发现
2006年下半年,笔者在山东临淄齐鲁石化驻地参与一个项目的开发。公司的另外一个项目《合同管理系统》正处于实施后期阶段。该项目采用.Net开发的B/S架构的系统,使用Oracle做后台数据库。先后两次发现,当在线用户较多的时候,客户端感觉服务系统反应很慢(多数用户报告在登录界面点击登录按钮后,一直处于等待状态,系统不再反应)。查看服务器使用情况,CPU和硬盘访问并不繁忙,内存占用也不是非常大;连接到数据库没有发现死锁,但是会话非常多,大约在110个左右。开始怀疑是数据库的进程(Processes)和会话(Sessions)设置的值较低(未安装时候的默认值,分别为170和150)。但是将这两个值扩大以后仍旧未解决问题。在第二次发现该问题的时候,我注意到虽然设置值较低,但是当前并未达到这两个值得上限;同时我也注意到该系统连接数据库的会话正好是100个,由此我联想到数据库连接池。
2.相关资料
使用连接字符串关键字控制连接池SqlConnection 对象的 ConnectionString 属性支持连接字符串键/值对,这些键/值对可用于调整连接池逻辑的行为。
ASP.NET连接数据库,数据库连接池默认是开启的,并且池中允许的最大连接数默认为100。由此基本可以确定,访问系统收到的阻碍时由于连接池已满造成的。
该页面中提到,如果连接池中的连接全部占用,系统会在连接池之外开启新的连接。这个说法有疑问,该问题在后面的会体积。
3.问题的确认
为了验证ASP.NET连接数据库时,连接池中的连接达到最大数,新的连接就需要等待连接池中的连接释放资源,我编写了一个测试页面,在页面装载的时候,首先打开10个连接,然后等待20秒钟后再关闭这些连接。随后使用测试机打开两个测试线程访问该测试页面,然后在浏览器中打开于这个测试页面使用相同连接字串的另外一个页面,发现后者的确需要等待测试线程访问的页面处理完毕之后才可以连接到数据库。
4.问题的解决
找到问题的症结所在,我们系统的ASP.NET连接数据库的字串,增加了Max Pool Size项,根据需要将其设置为200。同时修改了Oracle服务器的的会话(Sessions)和进程(Progresses)的值以满足连接会话的需要。
5.疑问
如前所述,资料中提及,如果连接池的连接全部占用,会创建新的连接。但是在采用默认连接池大小和设置为20个最大连接数的时候,连接池的所有连接全部占用,新的连接请求并没有开启新的连接会话,而是等待连接池中的连接释放。
但是连接池最大连接数设置为200个的时候,该系统的连接曾经一度超过200个上限,达210多个。由此可以判断超出的连接请求在连接池之外创建了新的连接会话,符合了资料中的论述。对此疑问,烦请知情者阐述一下自己的观点。
6.补充
在连接字串修改之后,原有的连接池会重新构建,这一特性是否可以在何种情况下应用?
【编辑推荐】