我们在制作中遇到了一个重要的应用程序问题。作为一个短期修复,我们在整个代码中的许多地方增加命令超时:
var cmd = new SqlCommand(szSQL, conn) {CommandTimeout = _cmdTimeout};
开发人员使用的初始默认值为500秒(8分钟以上)。在我们获得长期解决方案之前,这是我们的解决方案。我担心的是使用的秒数。 8分钟似乎很长一段时间(太长时间),我想知道使用这段时间可以引入哪些其他问题。试着留3-4分钟会更好吗?或者8岁就好了吗?
答案 0 :(得分:2)
我认为在必要时使用8分钟作为暂停是没有问题的。 AFAIK,SSMS在运行查询时有无限超时!
我建议根据提取的代码略有不同的方法:
private static bool IsRetryAfterException(SqlException aSqlExc)
{
if (aSqlExc != null)
{
// If anybody finds a better way than this, please update!
return aSqlExc.Message.Contains("The timeout period elapsed prior to completion of the operation or the server is not responding");
}
else
throw new ArgumentNullException("The parameter 'aSqlExc' cannot be null.");
}
private int CallExecuteNonQuery(SqlCommand aCmd)
{
for (int iRetry = 1; iRetry <= m_MaxTimeoutRetry; iRetry++)
try
{
return aCmd.ExecuteNonQuery();
}
catch (SqlException wSqlE)
{
if (iRetry == m_MaxTimeoutRetry || !IsRetryAfterException(wSqlE))
throw;
// otherwise, we double the timeout and retry
aCmd.CommandTimeout = 2 * aCmd.CommandTimeout;
// let SQL breathe a bit!
System.Threading.Thread.Sleep(aCmd.CommandTimeout * 10);
}
// This code cannot be reached but the compiler thinks otherwise
// this is because it cannot know that m_MaxTimeoutRetry is always >= 1 for the for-loop
throw new DataAccessException();
}
在我们的代码中,所有查询都是通过CallExecuteNonQuery方法调用的。 您可能很难更改代码,但可以使用Lambda表达式并轻松修改现有代码,以便通过非常少的更改来完成该独特方法...
所以问题是为什么使用循环并重试?这是因为SQL死锁。我的经验是,最好让一个命令超时快速说出30秒,如果它超时,并且让SQL呼出超出,而不是让所有查询在默认情况下都有很长的时间,则重试。
我希望这有帮助并且有意义。