• 背景:

在最近开发中遇到一个问题,对一个数据库进行操作时,我采用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 时,池程序在创建线程的当前事务上下文中自动登记连接。可识别的值为 truefalseyes 和no

Load Balance Timeout

0

连接被销毁前在连接池中生存的最短时间(以秒为单位)。

Max Pool Size

100

池中允许的最大连接数。

Min Pool Size

0

池中允许的最小连接数。

Pooling

'true'

当该值为 true 时,系统将从适当的池中提取 SQLConnection 对象,或在需要时创建该对象并将其添加到适当的池中。可识别的值为 truefalseyes 和 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.的更多相关文章

  1. 网站错误记录:Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool.

    今天看公司项目的错误日志文件,发现日志文件都是记录的这个错误. 经过网站查找,发现英文翻译是: 译:超时,与连接池的连接时间已过.这种情况发生是因为连接池在使用和最大连接池数目已满 通过翻译,可以看出 ...

  2. SSRS 2008 R2 错误:Timeout expired. The timeout period

    今天遇到了Reporting Services(SQL SERVER 2008 R2)的报表执行异常情况,报表加载数据很长时间都没有响应,最后报"An error occurred with ...

  3. Connection open error . Connection Timeout Expired. The timeout period elapsed during the post-login phase.

    是这样的,最近我在开发Api(重构),用的数据库是Sqlserver,使用的Orm是 SqlSugar(别问我为什么选这个,boss选的同时我也想支持国人写的东西,且文档也很全). 被催的是,写好了程 ...

  4. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

    今天碰到了一个查询异常问题,上网查了一下,感谢原创和译者 如果你使用的数据库连接类是 the Data Access Application Blocks "SqlHelper" ...

  5. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.【转】

    今天碰到了一个查询异常问题,上网查了一下,感谢原创和译者 如果你使用的数据库连接类是 the Data Access Application Blocks "SqlHelper" ...

  6. 记录一次在生成数据库服务器上出现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 ...

  7. 解决 Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. 的问题

    在web 网站开发中,经常需要连接数据库,有时候会出现这样的数据连接异常消息: 主要原因是 应用程序与数据库的连接超出了数据库连接的默认时长,在这种情况下,我们可以把数据库连接的时长延长一些,因为 C ...

  8. [bug]Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding

    写在前面 在mysql中这个异常是非常常见的,超时分为连接超时和执行超时,而连接超时,大部分原因是网络问题,或客户端到服务端的端口问题造成. bug场景 有的时候,使用MySqlDataReader在 ...

  9. The timeout period elapsed prior to completion of the operation or the server is not responding.

    问题:更新数据的状态值时,部分报出如下异常: 即时有成功更新,时有报错问题出现. 在LOG中发现成功更新的数据,存在更新时间过长问题,将近30秒(EF默认的CommandTimeout为30秒): 代 ...

随机推荐

  1. 一台电脑安装两个xampp的方法

    如果一台机器已经有一个xampp..如果还需要安装另外一个不同版本的xampp(里面PHP,mysql不同版本之类的)用做测试.则可以安装绿色版(不需注册,解压就可用) 下载地址(第二个xampp只能 ...

  2. vFloppy1.5-虚拟启动软盘

    vFloppy1.5为纯绿色免费软件,安装后不需要引导盘即可进入DOS,支持图形化访问NFTS系统格式,还可添加由光盘启动菜单选项,对于没有光驱,软驱的朋友非常实用. 到BIOS设置由光盘启动,或者打 ...

  3. embody the data item with the ability to control access to itself

    Computer Science An Overview _J. Glenn Brookshear _11th Edition Such communication needs have long b ...

  4. Java内存管理和垃圾回收

    笔记,深入理解java虚拟机 Java运行时内存区域 程序计数器,线程独占,当前线程所执行的字节码的行号指示器,每个线程需要记录下执行到哪儿了,下次调度的时候可以继续执行,这个区是唯一不会发生oom的 ...

  5. Andrew Ng机器学习公开课笔记–Independent Components Analysis

    网易公开课,第15课 notes,11 参考, PCA本质是旋转找到新的基(basis),即坐标轴,并且新的基的维数大大降低 ICA也是找到新的基,但是目的是完全不一样的,而且ICA是不会降维的 对于 ...

  6. GATT 服务器与客户端角色

    两个设备应用数据的通信是通过协议栈的GATT层实现的.从GATT角度来看,当两个设备建立连接后,他们处于以下两种角色之一: GATT服务器: 它是为GATT客户端提供数据服务的设备 GATT客户端:  ...

  7. nrf51822-提高nordic ble数据发送速率

    讲解2点: 为什么 nordic的4.0协议栈中ble只能发送20字节的应用负载数据. 大量数据发送时如何提高发送速率 1:为何上层应用负载每次最多20字节 首先了解 4.0中链路层的包格式如下: P ...

  8. FastReport的交叉表实际使用的一个例子

    计算发行-->定义份数月表(打开)出现 PosFraisPaysInput选择时间段后,点击“打印”.这个设计表格,就是交叉表. 交叉表的特点是:数据库是一条一条并列的但是出来的结果却是:横向是 ...

  9. 使用C++还是QML

    本质上,Qt 是一个C++类库.在引入 QML 以前,所有的开发都是基于 C++ 的,但到了 Qt 5,QML 和 Qt Quick 成为了 Qt 的核心之一,导致很多初学者在犹豫是否还需要学习 C+ ...

  10. Compiling Inkscape on Windows

    http://wiki.inkscape.org/wiki/index.php/Compiling_Inkscape_on_Windows http://www.oschina.net/news/80 ...