当SqlDataReader.Read()错误地返回false时,我如何解决这些问题?

时间:2014-04-16 09:56:07

标签: c# .net sql-server azure-sql-database sqldatareader

我正面临一些与this one类似的短暂问题。我的程序与SQL Azure保持开放连接。它使用以下代码来调用SQL查询:

using (var transaction = connection.BeginTransaction()) {
    using (var command = connection.CreateCommand()) {
        command.Transaction = transaction;
        command.CommandText = "MyQueryText";
        using( var reader = command.ExecuteReader() ) {
           if( reader.Read() ) {
              //retrieve data
           } else {
              // Control should not get here
              // but sometimes it gets here
              throw new InvalidOperationException()
           }
        } 
   } 
}

在某些时候,程序会运行上面的代码并面对SqlExceptionClass设置为12Number设置为-2,文字如下:

  

超时已过期。操作完成之前经过的超时时间或服务器没有响应。

等待15秒,关闭连接,打开连接并再次运行上面的代码。大多数情况下,第二次尝试要么成功,要么产生另一个SqlException超时。但有时 - 很少 - 控制传递给if,然后.Read()返回false并从我的代码中抛出异常。

查询的制作方式应至少返回一行(并且数据库中的数据应使查询至少返回一行),而.Read()仍返回false

这很少发生,随机发生,并且在此之前不久就会发生超时。我怀疑这是.NET框架错误处理的一些暂时性问题。像这样:

  • .ExecuteReader()发起查询
  • 服务器确认查询已成功运行
  • 发生一些网络错误
  • .Read()无法读取数据并返回false

我需要以某种方式解决这个问题 - 最好是这样的方式,如果有一个短暂的问题,它被正确诊断,并向调用者代码抛出适当的异常,并且重试逻辑处理这个。像这样:

using( var reader = command.ExecuteReader() ) {
   if( reader.Read() ) {
      //retrieve data
   } else if (reader.SomeTransientProblemOccured {
       throw new RetryTheQueryException();
   } else {
       throw new InvalidOperationException()
   } 
}

但我不知道如何确定存在这种短暂的问题。

我如何知道SqlDataReader.Read()因为暂时性问题而返回false而不是因为没有返回数据?

0 个答案:

没有答案