500秒命令超时 - 太长了?

时间:2013-08-05 20:24:13

标签: c# sql-server

我们在制作中遇到了一个重要的应用程序问题。作为一个短期修复,我们在整个代码中的许多地方增加命令超时:

var cmd = new SqlCommand(szSQL, conn) {CommandTimeout = _cmdTimeout};

开发人员使用的初始默认值为500秒(8分钟以上)。在我们获得长期解决方案之前,这是我们的解决方案。我担心的是使用的秒数。 8分钟似乎很长一段时间(太长时间),我想知道使用这段时间可以引入哪些其他问题。试着留3-4分钟会更好吗?或者8岁就好了吗?

1 个答案:

答案 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呼出超出,而不是让所有查询在默认情况下都有很长的时间,则重试。

我希望这有帮助并且有意义。