我正面临一些与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()
}
}
}
}
在某些时候,程序会运行上面的代码并面对SqlException
,Class
设置为12
,Number
设置为-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
而不是因为没有返回数据?