Как найти то, что использует соединения в моем пуле соединений - PullRequest
10 голосов
/ 06 июля 2011

У меня проблема с кодом, написанным с использованием .NET.

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

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

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

Итак, мой вопрос:

Есть ли способ запросить пул соединений, чтобы выяснить, что делают его используемые соединения. Я просто ищу способ выяснить, какой запрос выполняется, чтобы я мог найти оскорбительный фрагмент кода.

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

Ответы [ 2 ]

12 голосов
/ 08 июля 2011

Есть ли способ запросить пул соединений, чтобы узнать, что его используются соединения.

Нет. На самом деле, нет. Пул соединений - это то, что ваше приложение поддерживает (на самом деле List<DbConnectionInternal>). Если вы действительно этого хотите, вы можете получить доступ к соединениям в пуле с помощью отражения или отладки, через локальное окно или окно наблюдения (см. Ниже), но оттуда вы не можете добраться до того, что происходит в этом соединении или какой объект должен был называться Connection.Close (или Dispose). Так что это не поможет

enter image description here

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

SPID Staus    Login Hostname  Blkby DBname Command          ....
---- -------  ----- --------- ----- ------ ---------------- 
79   sleeping uName WebServer .     YourDb AWAITING COMMAND .....
80   sleeping uName WebServer .     YourDb AWAITING COMMAND .....
81   sleeping uName WebServer .     YourDb AWAITING COMMAND .....
82   sleeping uName WebServer .     YourDb AWAITING COMMAND .....

Это означает, что да, действительно, ваше приложение открыло много соединений, не закрыло их и даже ничего не делает с ними.

Лучший способ борьбы с этим - профилировать ваше приложение, используя Счетчики производительности ADO.NET , внимательно следить за NumberOfReclaimedConnections, а также тщательно анализировать код.

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

using (SqlConnection cnn = new SqlConnection("YourCnnString"))
{

     try
     {
            cnn.Open();
     }
     catch (InvalidOperationException)
     {
             SqlConnection.ClearPool(cnn);
     }
     cnn.Open();

}

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

2 голосов
/ 06 июля 2011

Вы пытались загрузить SSMS и запустить sp_who2 для рассматриваемой базы данных?

USE [SomeDatabase]
EXEC sp_who2

Это должно показать вам, что происходит в данный момент времени.

...