W większości przypadków problemy z pulą połączeń są związane z nieszczelnościami połączeń . Twoja aplikacja prawdopodobnie nie zamyka poprawnie i konsekwentnie połączeń z bazą danych. Gdy pozostawisz otwarte połączenia, pozostaną one zablokowane, dopóki moduł odśmiecania pamięci .NET nie zamknie ich za Ciebie, wywołując ich Finalize()
metoda.
Chcesz się upewnić, że naprawdę zamykasz połączenie . Na przykład poniższy kod spowoduje wyciek połączenia, jeśli kod pomiędzy .Open
i Close
zgłasza wyjątek:
var connection = new SqlConnection(connectionString);
connection.Open();
// some code
connection.Close();
Prawidłowy sposób to:
var connection = new SqlConnection(ConnectionString);
try
{
connection.Open();
someCall (connection);
}
finally
{
connection.Close();
}
lub
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
someCall(connection);
}
Gdy funkcja zwraca połączenie z metody klasy upewnij się, że buforujesz go lokalnie i wywołaj jego Close
metoda. Uwolnisz połączenie za pomocą tego kodu, na przykład:
var command = new OleDbCommand(someUpdateQuery, getConnection());
result = command.ExecuteNonQuery();
connection().Close();
Połączenie zwrócone z pierwszego wywołania getConnection()
nie jest zamykana. Zamiast zamykać połączenie, ta linia tworzy nowe i próbuje je zamknąć.
Jeśli używasz SqlDataReader
lub OleDbDataReader
, zamknij je. Mimo że samo zamknięcie połączenia wydaje się załatwiać sprawę, włóż dodatkowy wysiłek, aby jawnie zamknąć obiekty czytnika danych, gdy z nich korzystasz.
Ten artykuł „Dlaczego pula połączeń jest przepełniona?” z MSDN/SQL Magazine wyjaśnia wiele szczegółów i sugeruje kilka strategii debugowania:
- Uruchom
sp_who
lubsp_who2
. Te systemowe procedury składowane zwracają informacje zsysprocesses
tabela systemowa, która pokazuje status i informacje o wszystkich działających procesach. Ogólnie rzecz biorąc, zobaczysz jeden identyfikator procesu serwera (SPID) na połączenie. Jeśli nazwałeś swoje połączenie za pomocą argumentu Nazwa aplikacji w ciągu połączenia, Twoje działające połączenia będą łatwe do znalezienia. - Użyj SQL Server Profiler z SQLProfiler
TSQL_Replay
szablon do śledzenia otwartych połączeń. Jeśli znasz Profiler, ta metoda jest łatwiejsza niż odpytywanie za pomocą sp_who. - Użyj Monitora wydajności do monitorowania pul i połączeń. Za chwilę omówię tę metodę.
- Monitoruj liczniki wydajności w kodzie. Możesz monitorować kondycję swojej puli połączeń i liczbę ustanowionych połączeń, używając procedur do wyodrębniania liczników lub używając nowych kontrolek .NET PerformanceCounter.