Лучший способ установить максимальное время ожидания соединения в SQL Server

Я знаю, что вы можете установить параметр Connection Timeout в ConnectionString, однако он устанавливает минимальное время ожидания, а не максимальное.

Мое приложение работает с удаленной базой данных, и ему необходимо затемнить экран серым цветом и дождаться восстановления соединения, если оно было потеряно. Я уже делаю это нормально, но иногда, когда соединение потеряно, требуется более 30 секунд, чтобы понять, что соединение потеряно, даже при минимальном значении параметра Connetion Timeout.

Я обнаружил, что соединение потеряно, потому что у меня есть поток, выполняющий опрос базы данных каждые 0,5 секунды, и я жду, пока он не выдаст исключение «Произошла ошибка, связанная с сетью или конкретным экземпляром, при установлении соединения с SQL Server».

Я хочу знать, есть ли хороший способ установить максимальный тайм-аут или другую альтернативу, чтобы быстрее обнаружить потерю соединения.

Изменить: я не знал, что также существует CommandTimeout. Он не работает идеально, но работает лучше. Его нужно устанавливать для каждого нового объекта DataContext, но это нормально. Я установил значение X, и, кажется, всегда требуется X + 5 секунд, чтобы вызвать исключение тайм-аута.


person André Santaló    schedule 19.12.2013    source источник
comment
Что вы имеете в виду под максимальным таймаутом подключения и в чем разница с минимальным таймаутом подключения?   -  person Steve    schedule 19.12.2013
comment
@Steve Когда я устанавливаю его на 5, например, это означает, что таймаут не будет раньше 5 секунд, это то, что я имею в виду под минимальным значением, и это то, как он работает ... он выбрасывает исключение на произвольное время через 5 секунд. Максимальный тайм-аут будет означать, что исключение будет сброшено в тот момент, когда оно превысит 5 секунд ожидания.   -  person André Santaló    schedule 19.12.2013
comment
хм, может быть, это сбивает с толку то, что интервал опроса вашего сервера намного меньше вашего таймаута? Думаю, должно быть наоборот. Вы открываете новое соединение каждый раз при опросе? Или опрос не зависит от самого соединения? Вы пробовали воспроизвести это локально без удаленного сервера? Поскольку соединение sql, случайно завершающееся через некоторое время после интервала тайм-аута, не кажется правильным, imho.   -  person DrCopyPaste    schedule 19.12.2013
comment
@DrCopyPaste Ну, внутри потока опроса у него есть метод, который делает запрос, поэтому не имеет значения интервал опроса, поскольку он будет заблокирован в этом методе до тех пор, пока исключение не будет сгенерировано или не завершится успешно.   -  person André Santaló    schedule 19.12.2013
comment
хммм, но все же кажется бесполезным опрашивать с более короткими интервалами, чем запрос может завершиться в худшем случае. (если во время опроса вы больше ничего не делаете)   -  person DrCopyPaste    schedule 19.12.2013
comment
ConnectionTimeout - это тайм-аут для подключения к серверу. CommandTimeout - это тайм-аут для возврата команды. Люди часто предполагают, что commandTimeout по умолчанию совпадает с connectionTimeout, но это не так. Установка connectionTimeout не влияет на commandTimout, вы должны устанавливать его каждый раз.   -  person Ben    schedule 19.12.2013
comment
@Ben, так если предположить, что у одного будет One connection per command, меньшее значение обоих выигрышей?   -  person DrCopyPaste    schedule 19.12.2013
comment
@DrCopyPaste, нет, таймаут соединения - это тайм-аут для соединения Open() вызова. Это вообще не относится к командам. CommandTimeout применяется к вызовам Execute или ExecuteScalar. Это вообще не относится к соединениям.   -  person Ben    schedule 19.12.2013


Ответы (2)


ConnectionTimeout - это тайм-аут для соединения Open() вызова. Это вообще не относится к командам. CommandTimeout относится к вызовам Execute или ExecuteScalar. Это вообще не относится к соединениям.

Чтобы применить CommandTimeout ко всем командам, вы должны делать это каждый раз, когда вы создаете объект Command.

person Ben    schedule 30.12.2013

Лучший способ, который я нашел, - это создать другой класс, чтобы определять, когда соединение было потеряно.

Этот класс создаст 2 потока, один из которых вызывает метод, чтобы проверить, существует ли база данных, а затем устанавливает флаг в значение true; и другой, который будет проверять, был ли флаг истинным через определенное время. Если по прошествии определенного времени он все еще был ложным, это означает, что соединение с базой данных было потеряно, и первый поток заблокирован в ожидании тайм-аута. Таким образом, мне не нужно ждать, пока истечет время ожидания, чтобы обнаружить это.

person André Santaló    schedule 09.01.2014