В большинстве случаев проблемы с пулами соединений связаны с «утечками соединений». Ваше приложение, вероятно, не закрывает свои подключения к базе данных правильно и последовательно. Когда вы оставляете соединения открытыми, они остаются заблокированными, пока сборщик мусора .NET не закроет их для вас, вызвав их метод Finalize()
.
Вы хотите убедиться, что действительно закрываете соединение . Например, следующий код вызовет утечку соединения, если код между .Open
и Close
выдает исключение:
var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();
Правильный путь будет следующим:
var connection = new SqlConnection(ConnectionString);
try
{
connection.Open();
someCall (connection);
}
finally
{
connection.Close();
}
или
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
someCall(connection);
}
Когда ваша функция возвращает соединение из метода класса , убедитесь, что вы кэшируете его локально и вызываете его метод Close
. Вы потеряете соединение, используя этот код, например:
var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close();
Соединение, возвращенное после первого вызова getConnection()
, не закрывается. Вместо того, чтобы закрывать ваше соединение, эта строка создает новое и пытается закрыть его.
Если вы используете SqlDataReader
или OleDbDataReader
, закройте их. Несмотря на то, что закрытие самого соединения, кажется, делает свое дело, приложите дополнительные усилия для явного закрытия объектов чтения данных при их использовании.
Эта статья " Почему переполнение пула соединений? " из журнала MSDN / SQL объясняет множество деталей и предлагает некоторые стратегии отладки:
- Выполнить
sp_who
или sp_who2
. Эти системные хранимые процедуры возвращают информацию из системной таблицы sysprocesses
, которая показывает состояние и информацию обо всех рабочих процессах. Как правило, вы увидите один идентификатор процесса сервера (SPID) для каждого соединения. Если вы назвали свое соединение, используя аргумент «Имя приложения» в строке соединения, ваши рабочие соединения будет легко найти.
- Используйте SQL Server Profiler с шаблоном SQLProfiler
TSQL_Replay
для отслеживания открытых соединений. Если вы знакомы с Profiler, этот метод проще, чем опрос с использованием sp_who.
- Используйте системный монитор для мониторинга пулов и соединений. Я обсуждаю этот метод через мгновение.
- Мониторинг счетчиков производительности в коде. Вы можете отслеживать состояние своего пула соединений и количество установленных соединений, используя процедуры извлечения счетчиков или используя новые элементы управления .NET PerformanceCounter.