给客户写了一个web服务,功能就是接收客户端传过来单据,做些数据校验后,保存到数据库中。
运行了一段时间,前几日客户反应说,有些单据上传了,但在系统里看不到。
看了看日志,发生了这样的异常:
Exception:超时时间已到。超时时间已到,但是尚未从池中获取连接。出现这种情况可能是因为所有池连接均在使用,并且达到了最大池大小。
Type:System.InvalidOperationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
参考了这篇文章
http://www.dezai.cn/blog/article.asp?id=226
第一步,绕开连接池大小限制。
先试着在创建连接的代码处,加了段Catch(InvalidOperationException)的代码,
捕获"连接池已满"异常,然后在连接字符串后面加上"Pooling=false;",也就是以非连接池方式再次创建连接,
避开连接池大小的限制。
改完代码后总是要测试的,试着发起100个调用web服务的请求,大概在处理到第50个请求左右时,开始出现"连接池已满"异常。
一开始的50条是在同1秒钟写入的,出现"连接池已满"异常后,差不多每隔一分钟会写入一条。
这样又写入几条后,弹出下面这个异常:等待web服务回应超时了(见图1)。
图1
把web服务的SendTimeout改成3分钟后(原先是1分钟),再次测试上传100条。
这次都上传成功了。前50条是在同1秒写入的,51~79,出现"连接池已满"异常,隔1分钟写入一条,80以后又变成同1秒写入的。(见图2)
虽然数据都能写入,但100条数据花了30分钟才写完,结果不令人满意。
第二步,回过头来寻找罪魁祸首。
造成池满的原因应该是连接泄露,用完了没关闭。检查了下代码,除了连接泄漏的问题外,还有打开多个连接的缘故。
数据检查、保存数据时分别打开了一个数据库连接,这样每次调用web服务就会创建2个数据库连接。
修改了下代码,使得在一个请求中就使用同一个数据库连接,最后关闭这个连接。
再次测试100条,5秒钟全部完成,而且一个"连接池已满"也没发生,可以交差了。