背景:
如今这版考试系统分为学生考试端和后台管理端。同一登陆页,学生输入学号、password进入考试界面,管理员输入username、password进入后台管理界面。平时没有学生考试时。后台管理界面学院下拉框能够正确的从数据库读取并载入数据,但有学生考试时。后台管理界面学院下拉框获取的数据有时为空,有时为脏数据。
我们所做的尝试:
1、再现数据载入不对场景
用LoadRunner压力測试程序模拟255人在线考试的过程,发现当考试人数达到50人时,后台管理界面開始出现上述数据载入不对问题。
2、验证数据库是否产生了死锁
我们在207serverIIS上公布两套同样的考试系统A、B,A、B考试系统訪问同一数据库,用LoadRunner模拟255人訪问A系统,当A系统出现数据载入不对问题时。用B系统登录后台管理,每次刷新数据都能正确载入。
因此得出结论,不是数据库的问题,不然B系统也会出现数据载入不对问题。
3、验证IIS分配给应用程序的虚拟内存和专用内存是否太小
我们用LoadRunner模拟255人訪问考试系统。当系统出现数据载入不对问题时。在IIS的应用程序池对考试系统进行回收操作,系统数据正确载入。一直刷新。过段时间数据又不能正常载入。我们在IIS的应用程序池把考试系统的虚拟内存和专用内存设置为最大值,刷新页面仍然出现数据载入不对问题。
4、优化SQLHelper类
在SQLHelper中用到了非常多Connection、SqlCommand、SqlDataAdapter、SqlDataReader,原来是放在Using中运行,为了确保上述操作在运行完后释放内存。又加入了try、catch、finally,在finally关闭SqlDataReader、SqlDataAdapter、SqlCommand、Connection,但结果数据仍是载入不对。
5、在数据库连接串加入MultipleActiveResultSets=true属性
因为在报的黄页中有一个错误提示是“There is already an open DataReader associated with this Command which must be closed first”,所以尝试在数据库连接串加入MultipleActiveResultSets=true属性。同意在单个连接上运行多重的数据库查询或存储过程。但结果数据仍是载入不对。
6、把数据库的连接池最大值由1200改为500
做了上述5步操作,问题还是没有解决。于是尝试着换个思路,数据库连接池是不是设置的太大了,把最大值由1200改为了500。问题解决。
我们能够在百度百科查一下数据库连接池的定义:数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。不管这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时。这些请求将被增加到等待队列中。
最小连接数:是连接池一直保持的数据库连接,所以假设应用程序对数据库连接的使用量不大。将会有大量的数据库连接资源被浪费;
最大连接数:是连接池能申请的最大连接数,假设数据库连接请求超过此数,后面的数据库连接请求将被增加到等待队列中。这会影响之后的数据库操作。
最小连接数与最大连接数相差太大:那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。
只是,这些大于最小连接数的数据库连接在使用完不会立即被释放,它将被放到连接池中等待反复使用或是空暇超时后被释放。
原来数据库连接池最大为1200。最小为300。系统初始化时创建300个数据库连接,之后假设连接数超过300,则创建新的连接。可实际系统执行过程中并未用过这么多的数据库连接,造成数据库连接(是一种关键的有限的昂贵的资源)的浪费。
问题尽管解决。但仍然有一个疑问:“为什么数据库连接池最大值设置太大会造成数据载入不对”?