Почему так много sp_resetconnections для пула соединений C #? - PullRequest
8 голосов
/ 07 июня 2009

У нас есть веб-сервис, закодированный в C #, который делает много обращений к базе данных MS SQL Server 2005. Код использует блоки «Использование» в сочетании с пулом соединений C #.

Во время трассировки SQL мы видели много-много обращений к sp_resetconnection. Большинство из них короткие <0,5 секунды, однако иногда мы получаем вызовы продолжительностью до 9 секунд. </p>

Из того, что я прочитал, sp_resetconnection относится к пулу соединений и в основном сбрасывает состояние открытого соединения. Мои вопросы:

  • Почему открытому соединению требуется сброс состояния?
  • Почему так много звонков!
  • Что может привести к тому, что вызов sp_reset connection займет нетривиальное количество времени.

Это для меня загадка, и я ценю любую помощь!

Ответы [ 4 ]

12 голосов
/ 07 июня 2009

Сброс просто сбрасывает вещи, так что вам не нужно переподключать для их сброса. Он очищает соединение от таких вещей, как операции SET или USE, поэтому каждый запрос имеет чистый лист.

Соединение все еще используется повторно. Вот обширный список 1006 *:

sp_reset_connection сбрасывает следующие аспекты соединения:

  • Сбрасывает все состояния и числа ошибок (например, @@ error)
  • Останавливает все EC (контексты выполнения), которые являются дочерними потоками родительского EC, выполняющего параллельный запрос
  • Он будет ожидать любых ожидающих операций ввода-вывода, которые ожидают
  • Это освободит любые удерживаемые буферы на сервере при подключении
  • Это разблокирует любые ресурсы буфера, которые используются соединением
  • Освобождает всю память, выделенную для подключения
  • Он очистит все рабочие или временные таблицы, созданные соединением
  • Это убьет все глобальные курсоры, принадлежащие соединению
  • Он закроет все открытые дескрипторы SQL-XML, которые открыты
  • Удаляет все открытые рабочие таблицы, связанные с SQL-XML
  • Он закроет все системные таблицы
  • Это закроет все пользовательские таблицы
  • Будет сброшено все временные объекты
  • Отмена открытых транзакций
  • Это будет дефект от распределенной транзакции при зачислении
  • Это уменьшит счетчик ссылок для пользователей в текущей базе данных; какой релиз общей блокировки базы данных
  • Освободит приобретенные замки
  • Выпустит любые ручки, которые могли быть приобретены
  • Сброс всех параметров SET к значениям по умолчанию
  • Будет сброшено значение @@ rowcount
  • Будет сброшено значение @@ идентификатора
  • Сбрасывает все параметры трассировки уровня сеанса, используя dbcc traceon ()

sp_reset_connection НЕ сбрасывается:

  • Контекст безопасности, поэтому пул соединений сопоставляет соединения на основе точной строки соединения
  • Если вы ввели роль приложения, используя sp_setapprole, поскольку роли приложения не могут быть восстановлены
  • Уровень изоляции транзакции (!)
1 голос
/ 10 июня 2009

В основном, звонки - это информация о состоянии. Если у вас есть какие-либо открытые DataReaders, это займет много времени, чтобы произойти. Это связано с тем, что ваши DataReaders содержат только одну строку, но могут тянуть больше строк. Каждый из них должен быть очищен, прежде чем можно будет выполнить сброс. Поэтому убедитесь, что вы используете все в операторах using () и не оставляете открытыми некоторые из ваших операторов.

Сколько всего соединений у вас работает, когда это происходит?

Если у вас максимум 5, и вы нажали все 5, то вызов сброса заблокирует - и это займет много времени. На самом деле это не так, он просто заблокирован в ожидании соединения в пуле, чтобы стать доступным.

Кроме того, если вы работаете в SQL Express, вы можете очень легко заблокироваться из-за требований многопоточности (это также может произойти в полноценном SQL Server, но гораздо менее вероятно).

Что произойдет, если вы отключите пул соединений?

1 голос
/ 07 июня 2009

sp_resetconnection будет вызываться каждый раз, когда вы запрашиваете новое соединение из пула. Это должно быть сделано, поскольку пул не может гарантировать пользователя (вы, программист, вероятно, :) оставили соединение в надлежащем состоянии. например Возврат старого соединения с незафиксированными транзакциями был бы ... плохим.

Число вызовов должно быть связано с числом раз, когда вы выбираете новое соединение.

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

1 голос
/ 07 июня 2009

Вот объяснение Что делает sp_reset_connection? , в котором говорится, в части "Слои API доступа к данным, такие как ODBC, OLE-DB и SqlClient, вызывают (внутреннюю) хранимую процедуру sp_reset_connection при повторном использовании соединения из пула соединений. Он делает это для сброса состояния соединения, прежде чем оно будет использовано повторно. " Затем он дает некоторые особенности того, что делает этот системный sproc. Это хорошо.

...