多线程Windows服务中的多个同时SQL连接超时

ALE*_*sos 25 sql-server multithreading connection-timeout

我有一个多线程Windows服务,我用VS 2010(.NET 4.0)开发,可以有几个到几十个线程,每个线程通过Internet从慢速服务器检索数据,然后使用本地数据库记录这个数据(因此进程受Internet限制,而不是LAN或CPU绑定).

有一些规律性,我从几个线程同时得到以下错误的洪水/乱舞/爆发:

System.Data.SqlClient.SqlException(0x80131904):超时已过期.操作完成之前经过的超时时间或服务器没有响应.

此错误的调​​用堆栈通常是:

在System.Data.ProviderBase.DbConnectionPool.GetConnection(DbConnection owningObject)

在System.Data.ProviderBase.DbConnectionFactory.GetConnection(DbConnection owningConnection)

在System.Data.ProviderBase.DbConnectionClosed.OpenConnection(DbConnection outerConnection,DbConnectionFactory connectionFactory)

在System.Data.SqlClient.SqlConnection.Open()

我没有在连接字符串中指定连接超时,并且此数据库中还有其他应用程序和进程.有没有人遇到过这种行为,如果有的话,采取了哪些措施来防止它?

我的数据访问层中最常用的方法如下所示,我所有其他DAL方法都遵循相同的方法:

using (SqlConnection con = new SqlConnection(GetConnectionString()))
using (SqlCommand cmd = new SqlCommand("AddGdsMonitorLogEntry", con))
{
    cmd.CommandType = CommandType.StoredProcedure;

    /* setting cmd.Parameters [snipped] */

    // We have been getting some timeouts writing to the log; wait a little longer than the default.
    cmd.CommandTimeout *= 4;

    con.Open();

    cmd.ExecuteNonQuery();
}
Run Code Online (Sandbox Code Playgroud)

非常感谢!

编辑

鉴于在镜像环境中发生这种情况的评论,我确实应该提到有问题的数据库是镜像的.它在SSMS中标记为"Principal,Synchronized","高安全性,无自动故障转移(同步)"模式.

编辑5/26/11

我在SQL Server日志中看不到任何问题.(我无法访问该服务器上的Windows事件查看器,但我已经要求有人找我.)

ALE*_*sos 15

根据今天刚刚创建的MSDN博客帖子(谷歌万岁!):

Microsoft已确认这是当前版本的ADO.NET中的一个问题.此问题将在ADO.NET版本中修复,随Visual Studio 2011一起提供.

在此期间,我们要求使用以下变通方法:

  1. 将连接字符串超时增加到150秒.这将使第一次尝试有足够的时间连接(150*.08 = 12秒)

  2. 在连接字符串中添加MinPool Size = 20.这将始终在池中保持至少20个连接,并且创建新连接的机会将会减少,从而减少出现此错误的可能性.

  3. 提高网络性能.将NIC驱动程序更新为最新固件版本.当您的NIC卡与某些可扩展网络包设置不兼容时,我们已经看到了网络延迟.如果您使用的是Windows Vista SP1或更高版本,则还可以考虑禁用接收窗口自动调整.如果您启用了NIC绑定,则禁用它将是一个不错的选择.

帖子本身是一个有趣的读物,谈论TCP/IP连接重试算法.并且对所有说"嘿,这看起来与镜像有关......"的人们感到荣幸!请注意有关此问题的评论"由于SQL Server响应缓慢或由于网络延迟".

啊!!!

感谢所有发布的人.现在我们都必须要求.NET Framework(或其他一些ADO.NET修补机制)的补丁,所以我们不必等待(并购买)Visual Studio 11 ......


小智 7

连接超时与命令超时不同.命令超时适用于建立连接时的情况,但由于某些内部原因,服务器无法在所需时间内返回任何结果.默认命令超时为30秒. http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.commandtimeout.aspx

尝试在连接字符串中指定连接超时.默认值是15秒,这可能是您看到问题的原因.您还可以在代码中指定连接超时:http: //msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx