Mam swoją logikę biznesową zaimplementowaną w prostych klasach statycznych z metodami statycznymi. Każda z tych metod otwiera / zamyka połączenie SQL po wywołaniu:
public static void DoSomething(string something)
{
using (SqlConnection connection = new SqlConnection("..."))
{
connection.Open();
// ...
connection.Close();
}
}
Myślę jednak, że unikanie otwierania i zamykania połączenia oszczędza wydajność . Kilka testów wykonałem już dawno temu z klasą OleDbConnection (nie jestem pewien co do SqlConnection) i zdecydowanie pomogło to tak działać (o ile pamiętam):
//pass the connection object into the method
public static void DoSomething(string something, SqlConnection connection)
{
bool openConn = (connection.State == ConnectionState.Open);
if (!openConn)
{
connection.Open();
}
// ....
if (openConn)
{
connection.Close();
}
}
Pytanie brzmi - czy powinienem wybrać metodę (a) czy metodę (b)? Czytałem na innym pytaniu związanym z przepełnieniem stosu, że buforowanie połączeń zaoszczędziło mi wydajności, nie muszę się wcale przejmować ...
PS. Jest to aplikacja ASP.NET - połączenia istnieją tylko podczas żądania internetowego. Nie jest to aplikacja ani usługa korzystna.
c#
sqlconnection
Alex
źródło
źródło
DbConnection.StateChange
zdarzenia, aby monitorować zmiany stanu połączenia (i może być przechowywane lokalnie), zamiastDbConnection.State
bezpośrednio sprawdzać właściwość. Pozwoli to zaoszczędzić koszty wydajności.Odpowiedzi:
Trzymaj się opcji a .
Pula połączeń to Twój przyjaciel.
źródło
Za każdym razem użyj metody (a). Kiedy zaczniesz skalować swoją aplikację, logika zajmująca się stanem stanie się prawdziwym problemem, jeśli tego nie zrobisz.
Pula połączeń działa zgodnie z opisem w puszce. Pomyśl tylko, co się dzieje, gdy aplikacja się skaluje i jak trudno byłoby ręcznie zarządzać stanem otwarcia / zamknięcia połączenia. Pula połączeń świetnie sobie z tym radzi. Jeśli martwisz się o wydajność, pomyśl o jakimś mechanizmie pamięci podręcznej, aby nic nie zostało zablokowane.
źródło
Zawsze zamykaj połączenia, gdy tylko z nimi skończysz, aby podstawowe połączenie z bazą danych mogło wrócić do puli i być dostępne dla innych wywołujących. Pule połączeń są dość dobrze zoptymalizowane, więc nie ma za to zauważalnej kary. Rady są zasadniczo takie same jak w przypadku transakcji - po zakończeniu powinny być krótkie i zamknięte.
Sytuacja staje się bardziej skomplikowana, jeśli napotykasz problemy z usługą MSDTC, używając pojedynczej transakcji wokół kodu, który używa wielu połączeń, w takim przypadku musisz udostępnić obiekt połączenia i zamknąć go dopiero po zakończeniu transakcji.
Jednak robisz to ręcznie, więc możesz chcieć zbadać narzędzia, które zarządzają połączeniami za Ciebie, takie jak DataSets, Linq to SQL, Entity Framework lub NHibernate.
źródło
Zastrzeżenie: wiem, że to jest stare, ale znalazłem łatwy sposób na zademonstrowanie tego faktu, więc wkładam moje dwa centy.
Jeśli nie możesz uwierzyć, że pooling będzie naprawdę szybszy, spróbuj:
Dodaj gdzieś:
Teraz wymienić wszystkie połączenia, aby
Open()
sięTimedOpen()
i uruchomić program. Teraz, dla każdego odrębnego ciągu połączenia, które posiadasz, okno konsoli (wyjściowe) będzie miało jedno długo działające otwarte i kilka bardzo szybkich otwarć .Jeśli chcesz nadać im etykietę, możesz dodać
new StackTrace(true).GetFrame(1) +
do połączenia doWriteLine
.źródło
Istnieją rozróżnienia między połączeniami fizycznymi i logicznymi. DbConnection jest rodzajem połączenia logicznego i wykorzystuje podstawowe połączenie fizyczne z Oracle. Zamykanie / otwieranie DbConnection nie wpływa na wydajność, ale sprawia, że kod jest czysty i stabilny - w tym przypadku wycieki połączenia są niemożliwe.
Należy również pamiętać o przypadkach, w których istnieją ograniczenia dla połączeń równoległych na serwerze db - biorąc pod uwagę, że konieczne jest, aby połączenia były bardzo krótkie.
Pula połączeń uwalnia Cię od sprawdzania stanu połączeń - wystarczy je otworzyć, użyć i natychmiast zamknąć.
źródło
np. kiedy użytkownik wykonuje akcję ładowania, Twoja aplikacja musi najpierw znaleźć saldo użytkownika i zaktualizować je, powinni używać tego samego połączenia.
Nawet jeśli ado.net ma swoją pulę połączeń, koszt wysyłki połączenia jest bardzo niski, ale ponowne użycie połączenia jest lepszym wyborem.
Ponieważ połączenie jest blokowane, gdy wykonujesz jakieś zapytanie lub polecenie, oznacza to, że aplikacja wykonuje tylko jedną operację bazy danych w tym samym czasie, jak niska jest wydajność.
Kolejną kwestią jest to, że Twoja aplikacja zawsze będzie miała połączenie, nawet jeśli Twój użytkownik po prostu ją otworzy, ale nie ma żadnych operacji.Jeśli jest wielu użytkowników, którzy otwierają Twoją aplikację, serwer db wkrótce będzie kosztował całe swoje źródło połączenia, podczas gdy Twoi użytkownicy nie. byle co.
źródło