编写一个非常简单的工具来ping SQL服务器并确保可以访问一堆连接字符串,我遇到了一个非常奇怪的问题:在迭代几十个连接字符串时,前半部分超时后我指定的大约多少秒(在这个特殊情况下为11)并记录相应的尝试和异常当前的墙壁时间,但突然间,其中大约十几个瞬间超时,然后恢复正常的超时。
这在一台计算机上运行,该计算机对所有要测试的连接字符串中使用的一个IP没有任何网络访问权限。在日志中它看起来像这样:
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:40 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:40 Connection name:
2018-04-06 15:59:54 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:54 Connection name:
2018-04-06 15:59:54 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 15:59:54 Connection name:
2018-04-06 16:00:08 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 16:00:08 Connection name:
2018-04-06 16:00:22 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 16:00:22 Connection name:
2018-04-06 16:00:35 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
2018-04-06 16:00:35 Connection name:
2018-04-06 16:00:49 SQL Error:Connection Timeout Expired. Th
or the server was unable to respond back in time. The duration s
看看如何在一堆即时超时后15:59:40在15:59:54记录的最后一个条目是正常的,然后另一个连接立即超时,并且在16:00:08之后的所有内容超时通常是。
代码看起来完美无缺的教科书:
foreach (ConnectionStringSettings cs in ConfigurationManager.ConnectionStrings)
{
if (cs.Name.Equals("LocalSqlServer") && !args.Contains("NoSkipLocal", StringComparer.OrdinalIgnoreCase)) continue;
SqlConnectionStringBuilder b = new SqlConnectionStringBuilder(cs.ConnectionString)
{
ConnectTimeout = timeout == 0 ? 10 : timeout
};
SqlConnection conn = new SqlConnection(b.ConnectionString);
try
{
conn.Open();
LogToConsole("Connection success", ConsoleColor.Green);
}
catch (SqlException sex)
{
LogToConsole("SQL Error:" + sex.Message, ConsoleColor.Red);
}
catch (Exception ex)
{
LogToConsole("Error:" + ex.Message, ConsoleColor.Red);
}
static void LogToConsole(string message, ConsoleColor color = ConsoleColor.Gray)
{
ConsoleColor fgColor = Console.ForegroundColor;
Console.ForegroundColor = color;
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\t" + message);
Console.ForegroundColor = fgColor;
}
是否有其他人使用ADO.NET SqlConnection对象体验即时超时?我期待连接失败很可能是即时的,但至少信息应该是不同的。但它与~14秒过去完全相同。
答案 0 :(得分:0)
将Pooling = false
添加到连接字符串构建器实例以解决此问题。现在每个连接在抛出异常之前等待指定的秒数。
在连接池打开时处理SqlConnection
是不够的,ADO.NET池仍然保存特定数据库的条目并存储上一个错误状态,因此在实例化下一个连接对象时如果连接字符串指向相同的连接,则会立即返回超时连接。
在我的特殊情况下,这是一个很好的行为,因为它节省了我测试连接字符串的时间,但在现实世界中它可能代表一种令人讨厌的副作用。