背景:
现在这版考试系统分为学生考试端和后台管理端。同一登陆页,学生输入学号、密码进入考试界面,管理员输入用户名、密码进入后台管理界面。平时没有学生考试时,后台管理界面学院下拉框可以正确的从数据库读取并加载数据,但有学生考试时,后台管理界面学院下拉框获取的数据有时为空,有时为脏数据。
我们所做的尝试:
1、再现数据加载不正确场景
用LoadRunner压力测试程序模拟255人在线考试的过程,发现当考试人数达到50人时,后台管理界面开始出现上述数据加载不正确问题。
2、验证数据库是否产生了死锁
我们在207服务器IIS上发布两套相同的考试系统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,则创建新的连接,可实际系统运行过程中并未用过这么多的数据库连接,造成数据库连接(是一种关键的有限的昂贵的资源)的浪费。
问题虽然解决,但仍然有一个疑问:“为什么数据库连接池最大值设置太大会造成数据加载不正确”?
版权声明:本文为博主原创文章,未经博主允许不得转载。