Пул соединения SQL Server не обнаруживает закрытые соединения?

В течение многих лет я испытывал очень странные проблемы на всех своих веб-приложениях, которые соединяются с SQL-сервером.

Проблема состоит в том, что, если что-то происходит с сервером базы данных (перезапуск сервера или другая проблема), de веб-приложение, прекращает работать от той точки над, даже если сервер базы данных жив и здоров впоследствии.

То, что происходит, - то, что каждая операция ADO.NET (ExecuteNonQuery, CreateReader, BeginTransaction...) перестала работать с InvalidOperationException: "Недопустимая операция. Соединение закрывается". SqlConnection кажется что вызов. Открытый () получает соединение от пула приложений, который... закрывается!

Согласно документации, пул соединения должен автоматически удалить разъединенные соединения из пула соединения, но по-видимому закрытое соединение не расценивается, как "разъединено", таким образом, вызов к SqlConnection. Открытый () счастливо возвращает закрытое соединение, предполагая, что это открыто, не проверяя это.

Мое текущее обходное решение должно проверить на состояние соединения прямо после открытия его:

using (SqlConnection connection = new SqlConnection( connectionString ))
{
   connection.Open();

   if (connection.State != ConnectionState.Open)
   {
      SqlConnection.ClearAllPools();

      connection.Open();
   }

   // ...
}

Это обходное решение, кажется, работает на данный момент, но я не чувствую себя комфортно, делая это.

Таким образом, мои вопросы:

  1. Почему делает SqlConnection. Открытый () возвращают закрытые соединения из пула соединения?
  2. Действительно ли мое обходное решение допустимо?
  3. Существует ли лучший способ обработать это?
18
задан Philippe Leybaert 28 January 2010 в 12:59
поделиться

2 ответа

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

  1. Даже когда вы закрываете соединение в коде, он возвращается в бассейн без подключения, находящегося непосредственно закрытому - готов к дальнейшему использованию.
  2. Если это соединение отрублено (т.е. SQL Server перезапускается), когда соединение возвращается из пула для другого вызывающего абонента для использования, и этот звонящий делает на нем .Open, это не ошибка при этом Точка, когда сервер базы данных все еще находится вниз. Это является частью преимущества Performance Pooking соединения, так как он на самом деле не возвращается на сервер базы данных для подключения.
  3. Когда вы фактически пытаетесь выполнить команду против соединения (например, ExecutenCeyery), именно в этом случае он на самом деле бросает исключение

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

Это были некоторые статьи, на которых я смотрел, в то время:
SQL Server Group Group
с использованием объединения соединения в ASP.NET

Редактировать:
Это не странно, что плохое соединение остается в Бассейн навсегда - вы уверены, что это определенно делает, и это не просто несколько плохих соединений? Если вы уверены, что звучит так, как эти соединения не выпускаются правильно в вашем коде. Это - еще одна очень хорошая статья, которую я прочитал некоторое время назад, что говорит (цитата):

автоматически промывает соединения

, если объединенное соединение остается в «Закрыто, но многоразовое» состояние для от 4 до 8 минут (интервал выбран случайным) соединение механизм объединения закрывает физический соединение и отбрасывает объединение связь. Это если число остальных соединений больше чем минимальные соединения настроен для пула (по умолчанию 0). Обратите внимание, что соединение должно были закрыты приложением (и выпущен обратно в бассейн) до Это может быть предметом автоматического релиз. Если вы не закрываете соединение в коде или сирот Объект подключения, объединение Механизм ничего не сделает. Не здесь не являются аргументами для подключения Измените значение времени ожидания.

12
ответ дан 30 November 2019 в 09:21
поделиться

Для автобоксирования используется некоторый механизм кэширования. Обычно никогда не следует полагаться на = = , всегда используйте равно для проверки равенства.

-121--3545962-

Это приведет к перехвату любого входного элемента, инициировавшего отправку:

$(document).ready(function() {
    var target = null;
    $('#form :input').focus(function() {
        target = this;
        alert(target);
    });
    $('#form').submit(function() {
        alert(target);
    });
});
-121--3515961-

С помощью ADO была обнаружена та же проблема, что и с C++. Несколько лет назад, после работы с Microsoft Support, мы также внедрили аналогичную логику повторных попыток в код и сбросили пул подключений, который разрешил проблему.

Если есть лучшее решение, люди в службе поддержки Майкрософт либо не знали об этом, либо не делились (в то время в любом случае).

2
ответ дан 30 November 2019 в 09:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: