SQLSERVER:Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
- 背景:
在最近开发中遇到一个问题,对一个数据库进行操作时,我采用64个并行的任务每个任务保证一个数据库连接对象;但是每个任务内部均包含有24个文件需要读取,在读取文件之后,我们需要快速将这24个文件批量入库到数据库中。
于是我这样开发我的程序:
主任务处理方式:最多允许64并行主任务;
主任务内部子任务采用串行方式:24个文件依次读取,和当前主任务均使用同一个数据库连接字符串。
每个主任务都需要24个文件入库到各自的物理分表中,采用的是串行读取文件资源,串行入库,没有能并行插入24个批处理文件到当前主任务的分表中,感觉到这可能是数据库IO入库速度不高是一个主要因素。
于是包主任务中的24个文件解析入库子任务改为并行方式,结果问题来了:
Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.
- 排查问题:
1、查看当前数据库已经占用的连接数方法:
A、通过perfiler监控我当前的连接数多少?采用Standard(default)监控模式,stop-》start,每次开始时,就会快速罗列出当前已经建立的连接列表,从列表记录中可以查看到目前数据库实例被占用的数据库连接数。

B、从sys.dm_os_performance_counters中查找
declare @value int;
while 1=1 begin
waitfor delay '00:00:01'
select @value=cntr_value from sys.dm_os_performance_counters where counter_name ='User Connections' print @value;
end
从上边的监控中查询出,目前我们的数据库连接数确实就只有100个左右,怎么就出现连接池满的问题。前50个是系统连接占用,不计算,那么,我们可以使用的连接数只有将近50个就出现连接池满的异常了。
吃惊!
我们查看下数据库连接数设置是否有问题,通过界面查看:

貌似一切正常,没有限制,难道100个连接就达到最大连接数了?!!!
我们执行查询最大连接数查询sql命令:
select * from sys.configurations where name ='user connections'

sqlserver难道在欺骗我们,绝不可能,那么大个公司,如果不能处理这么多,就不会不负责人多高数用户最多允许32767个连接。
我们注意到,这里的value_in_use字段和从数据库界面上看到的一样,都是0,没有限制,那么就是说我们默认就是不受限制,可以最多使用32767个连接。
- 问题发现:
那么,是谁给我们制定了最大连接数限制为100呢?
记得在数据库连接字符串中是包含这个设置的Max Pool Size属性,赶快查查MSDN,确认下是不是这里不写的话有默认值。
搜索关键字“SqlConnection.ConnectionString 属性”,找打了MSDN:https://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlconnection.connectionstring(VS.80).aspx
|
名称 |
默认值 |
说明 |
|---|---|---|
|
Connection Lifetime |
0 |
当连接被返回到池时,将其创建时间与当前时间作比较,如果时间长度(以秒为单位)超出了由 Connection Lifetime 指定的值,该连接就会被销毁。这在聚集配置中很有用(用于强制执行运行中的服务器和刚置于联机状态的服务器之间的负载平衡)。 零 (0) 值将使池连接具有最大的连接超时。 |
|
Connection Reset |
'true' |
确定从池中提取数据库连接时是否重置数据库连接。对于 SQL Server 7.0 版,设置为 false 可避免获取连接时再有一次额外的服务器往返行程,但须注意此时并未重置连接状态(如数据库上下文)。 只要不将 Connection Reset 设置为 false,连接池程序就不会受到 ChangeDatabase 方法的影响。连接在退出相应的连接池以后将被重置,并且服务器将移回登录时数据库。不会创建新的连接,也不会重新进行身份验证。如果将 Connection Reset 设置为 false,则池中可能会产生不同数据库的连接。 |
|
Enlist |
'true' |
当该值为 true 时,池程序在创建线程的当前事务上下文中自动登记连接。可识别的值为 true、false、yes 和no。 |
|
Load Balance Timeout |
0 |
连接被销毁前在连接池中生存的最短时间(以秒为单位)。 |
|
Max Pool Size |
100 |
池中允许的最大连接数。 |
|
Min Pool Size |
0 |
池中允许的最小连接数。 |
|
Pooling |
'true' |
当该值为 true 时,系统将从适当的池中提取 SQLConnection 对象,或在需要时创建该对象并将其添加到适当的池中。可识别的值为 true、false、yes 和 no。 |
当设置需要布尔值的关键字或连接池值时,您可以使用“yes”代替“true”,用“no”代替“false”。整数值表示为字符串。
Max Pool Size 默认为100。
- 问题验证:
问题终于锁定了,那么是否真的是这样子呢?
我做了一下测试:
class Program
{
static void Main(string[] args)
{
ThreadPool.SetMaxThreads(, ); for (var i = ; i < ; i++)
{
ThreadPool.QueueUserWorkItem(Connection);
} while (true)
{
Thread.Sleep();
Console.WriteLine("alive...");
} Console.WriteLine("Complete!!!");
Console.ReadKey();
} private static void Connection(object state)
{
SqlConnection connection = new SqlConnection("Data Source=.;Initial Catalog=i_Master;Persist Security Info=True;User ID=NUser;Password=N2;max pool size=500"); connection.Open(); using (SqlCommand command = new SqlCommand())
{
command.Connection = connection;
command.CommandTimeout = * ;
command.CommandText = @"
SELECT @@VERSION;
waitfor delay '00:00:01'
";
command.CommandType = System.Data.CommandType.Text; command.ExecuteNonQuery();
} Thread.Sleep();
}
}
我设定1000个线程,在.net线程池中运行,每个线程打开数据库连接字符串后不关闭,让他永久占用连接,直到对象被回收或者连接超时。
通过上边两种监控连接的方式,查看到的结果:
A方式监控结果:

B方式监控结果:

- 参考资料:
Configure the user connections Server Configuration Option:https://technet.microsoft.com/en-us/library/ms187030.aspx
Connection Pooling and the “Timeout expired” exception FAQ:https://blogs.msdn.microsoft.com/angelsb/2004/08/25/connection-pooling-and-the-timeout-expired-exception-faq/
Max Connection Pool capped at 100:http://dba.stackexchange.com/questions/51219/max-connection-pool-capped-at-100
SqlConnection.ConnectionString 属性:https://msdn.microsoft.com/zh-cn/library/system.data.sqlclient.sqlconnection.connectionstring(VS.80).aspx
SQLSERVER:Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.的更多相关文章
- 网站错误记录:Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool.
今天看公司项目的错误日志文件,发现日志文件都是记录的这个错误. 经过网站查找,发现英文翻译是: 译:超时,与连接池的连接时间已过.这种情况发生是因为连接池在使用和最大连接池数目已满 通过翻译,可以看出 ...
- SSRS 2008 R2 错误:Timeout expired. The timeout period
今天遇到了Reporting Services(SQL SERVER 2008 R2)的报表执行异常情况,报表加载数据很长时间都没有响应,最后报"An error occurred with ...
- Connection open error . Connection Timeout Expired. The timeout period elapsed during the post-login phase.
是这样的,最近我在开发Api(重构),用的数据库是Sqlserver,使用的Orm是 SqlSugar(别问我为什么选这个,boss选的同时我也想支持国人写的东西,且文档也很全). 被催的是,写好了程 ...
- Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
今天碰到了一个查询异常问题,上网查了一下,感谢原创和译者 如果你使用的数据库连接类是 the Data Access Application Blocks "SqlHelper" ...
- Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.【转】
今天碰到了一个查询异常问题,上网查了一下,感谢原创和译者 如果你使用的数据库连接类是 the Data Access Application Blocks "SqlHelper" ...
- 记录一次在生成数据库服务器上出现The timeout period elapsed prior to completion of the operation or the server is not responding.和Exception has been thrown by the target of an invocation的解决办法
记一次查询超时的解决方案The timeout period elapsed...... https://www.cnblogs.com/wyt007/p/9274613.html Exception ...
- 解决 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 的问题
在web 网站开发中,经常需要连接数据库,有时候会出现这样的数据连接异常消息: 主要原因是 应用程序与数据库的连接超出了数据库连接的默认时长,在这种情况下,我们可以把数据库连接的时长延长一些,因为 C ...
- [bug]Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding
写在前面 在mysql中这个异常是非常常见的,超时分为连接超时和执行超时,而连接超时,大部分原因是网络问题,或客户端到服务端的端口问题造成. bug场景 有的时候,使用MySqlDataReader在 ...
- The timeout period elapsed prior to completion of the operation or the server is not responding.
问题:更新数据的状态值时,部分报出如下异常: 即时有成功更新,时有报错问题出现. 在LOG中发现成功更新的数据,存在更新时间过长问题,将近30秒(EF默认的CommandTimeout为30秒): 代 ...
随机推荐
- iOS标准时间与时间戳相互转换
iOS标准时间与时间戳相互转换 (2012-07-18 17:03:34) 转载▼ 标签: ios 时间戳 标准时间 格式 设置 转化 杂谈 分类: iPhone开发 设置时间显示格式: NS ...
- JavaScript 数组详解(转)
在程序语言中数组的重要性不言而喻,JavaScript中数组也是最常使用的对象之一,数组是值的有序集合,由于弱类型的原因,JavaScript中数组十分灵活.强大,不像是Java等强类型高级语言数组只 ...
- 初学Java,第一段代码
public class myapp { public static void main(String[] args) { // TODO Auto-generated method stub Sys ...
- Delphi下使用MapWinGIS控件打开GIS图层
unit Unit3; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System ...
- SQuirreL 连接 hive
软件安装版本: hadoop-2.5.1 hbase-0.98.12.1-hadoop2 apache-hive-1.2.1-bin SQuirreL SQL Client3.7 集成步骤: 1. S ...
- sql 语句查询练习题
1. 查询Student表中的所有记录的Sname.Ssex和Class列. select sname,ssex,class from student 2. 查询教师所有的单位即不重复的Depart列 ...
- Chart控件,把Y轴设置成百分比
这次所有属性设置都用代码(就当整理便于以后查询). 在窗体放置一个Chart控件,未做任何设置:然后编写代码: //设置 chart2.Legends[ ].Enabled = false;//不显示 ...
- JavaScript操作数组
数组被描述为一个存储元素的线性集合,元素可以通过索引来任意存取. 几乎所有的编程语言都有类似的数据结构,但是Javascript中的数组却略有不同. Javascript中的数组是一种特殊的对象,所以 ...
- 一个短小的JS函数,用来得到仅仅包含不重复元素的数组
下面函数主要利用了数组的sort方法,之后的逻辑是看最后一个元素是否等于要添加的元素,如果不是就往尾后加. 这个做法的效率等于sort方法的效率,还过得去. 代码: <!DOCTYPE HTML ...
- iOS FMDB官方使用文档 G-C-D的使用 提高性能(翻译)(转)
由于FMDB是建立在SQLite的之上的,所以你至少也该把这篇文章从头到尾读一遍.与此同时,把SQLite的文档页 http://www.sqlite.org/docs.html 加到你的书签中.自动 ...