Лучший способ обрабатывать sql-соединения в веб-сервисе? - PullRequest
1 голос
/ 06 января 2009

У меня есть веб-сервис, который вызывается до 10 клиентов. Веб-сервис состоит из 7 различных страниц asmx и имеет около 100-200 функций на каждой странице.

Все эти функции работают с базой данных MSSQL2005 или MS SQL2000. В некоторые периоды дня это большой трафик от клиентов, и кажется, что у меня заканчиваются соединения на sql-сервере, что приводит к остановке всех клиентов.

В каждой функции я открываю соединение, делаю вещи, а затем закрываю соединение, иногда с транзакциями, иногда без.

На сервере я вижу, что он создает много соединений, я не знаю, почему они не исчезают, но остаются там даже после того, как функция выполнена и завершена. Итак, я могу сказать, что мои 10 клиентов время от времени создают более 80 соединений. Иногда некоторые из них уходят, иногда они остаются там через несколько часов после использования. Там происходит какое-то объединение?

Вопрос 1: Есть ли другой способ обработки соединений, которые я должен использовать, например, одно глобальное соединение для веб-службы или каким-либо другим способом?

Вопрос 2: Если нормально обрабатывать соединения для каждой функции, то почему он не закрывает соединение на сервере, делая список открытых соединений все больше и больше, пока я не выйду из ошибки соединений?

Этот вопрос относится к другому моему вопросу, но не к нему: Странная проблема SQL2005. «SqlConnection не поддерживает параллельные транзакции»

Теперь я сужу его до ошибки «Нет соединения».

Ответы [ 3 ]

4 голосов
/ 07 января 2009

Я согласен с комментарием о рефакторинге, но здесь это не относится к делу.

Вам определенно следует использовать соединение в каждой функции, и это звучит так, как будто вы их неправильно распределяете. Предполагая, что операции с базой данных содержатся в вызываемой функции, ваш код должен выглядеть примерно так:

using (SqlConnection connection = <connection code>)
{
  using (SqlCommand command = <command code>)
  {
    // Execute.
  }
}

На стороне сервера соединения будут оставаться открытыми. По умолчанию класс SqlConnection включает пул соединений, поэтому вы увидите, что соединение открыто на стороне сервера.

Это нормальное поведение, и его следует ожидать.

3 голосов
/ 07 января 2009

Вы действительно видите пул соединений в действии. Это происходит по умолчанию в .Net 2+ для SQL 2005 (не уверен насчет других версий).

Пул подключений означает, что .Net будет держать открытым несколько подключений для вас, так что будет меньше затрат при следующем подключении. CLR может просто дать вам уже открытое (и очищенное) соединение, которое в несколько сотен раз быстрее, чем переподключение к базе данных напрямую. Когда вы вызываете connection.Close (), вы просто возвращаете соединение с пулом для повторного использования.

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

Вы видите проблемы, потому что вы подключаетесь к 100 соединениям - максимальная сумма по умолчанию в пуле (по умолчанию минимум 0). В этот момент пул не сможет обеспечить другое соединение, пока оно не будет переработано, поэтому приложение будет зависать или истечет время ожидания. Вам нужно изменить строку подключения, чтобы она включала более высокое максимальное число (а также посмотреть на сокращение количества подключений).

0 голосов
/ 06 января 2009

То есть 700-1400 функций в одном веб-сервисе? Звучит слишком много для меня. Время рефакторинга.

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

...