У меня есть код, который периодически запускает запрос к базе данных SQL Server и сохраняет строки в словаре. Этот код работает нормально в нашей производственной среде около 3 лет. Совсем недавно он рушился с необработанным исключением. Для устранения неполадок я удалил все, кроме чтения столбца, и завернул все в try-catch. Вот исключение:Исключение таймаута SqlDataReader
Первый шанс исключение типа «System.Data.SqlClient.SqlException» произошло в System.Data.dll Время ожидания истекло. Период ожидания истекает до завершения операции или сервер не отвечает.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error) at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParserStateObject.ReadNetworkPacket() at System.Data.SqlClient.TdsParserStateObject.ReadByteArray(Byte[] buff, Int32 offset, Int32 len) at System.Data.SqlClient.TdsParser.SkipValue(SqlMetaDataPriv md, TdsParserStateObject stateObj) at System.Data.SqlClient.TdsParser.SkipRow(_SqlMetaDataSet columns, Int32 startCol, TdsParserStateObject stateObj) at System.Data.SqlClient.SqlDataReader.CleanPartialRead() at System.Data.SqlClient.SqlDataReader.ReadInternal(Boolean setTimeout)
Я использую что-то очень похожее на:
// query is a simple select from 1 table, not long running by any means
string query = "SELECT col1, col2, col3, col4 FROM db.dbo.tbl_name WITH (nolock)"; //connection timeout
string query = "SELECT col1, col2, col3, col4 FROM db.dbo.tbl_name WITH (nolock) order by col1, col2"; //connection does not time out
SqlCommand command = new SqlCommand(query,connection)
SqlDataReader reader = command.ExecuteReader();
while (!reader.IsClosed && reader.Read()) {
try {
string test0 = reader[0].ToString();
string test1 = reader[1].ToString();
string test2 = reader[2].ToString();
string test3 = reader[3].ToString();
// here is where I would normally processes and store into dictionary
}
catch (Exception e){
//make some noises
}
}
При запуске запроса с другими методами, он возвращает практически мгновенно (а под второй), но только чтобы увидеть, что произойдет, я увеличил CommandTimeout
до 60 секунд (по умолчанию 30), что только увеличило время, в течение которого моя программа зависала, прежде чем выбрасывать исключение.
По предложению @ frisbee я добавил запрос к предложению, который останавливает соединение с тайм-аутом.
Я думаю, что одна из операций Read()
не возвращается, а затем вызывает соединение с таймаутом, но я понятия не имею, что может вызвать это. Обычно это происходит в определенной строке при чтении столбца 3, но не всегда. Запрос возвращает чуть менее 50 тыс. Строк, и иногда он будет проходить через все, а иногда только через 15 тыс.
Если вы подозреваете, что доступ к столбцам является виновником, удалите его (для устранения целей ...). агрегировать 'reader.FieldCount' в' int' внутри вашего цикла и ничего не делать (это просто так, чтобы вы «касались» каждой строки каким-то образом). см., если вы все еще получаете свои тайм-ауты. – Amit
Тот же результат, за исключением того, что он выдает исключение в Read() – Pete
, поэтому теперь вы знаете, что это не столбцы (вряд ли начинались). Я был бы очень удивлен, если это действительно не проблема с БД. Что изменилось с 3 лет назад? больше данных? – Amit