Singleton SqlConnection vs SqlConnection per user

0

Witam ... jako, że pierwszy raz także pozdrawiam.

Może nie tyle co mam problem co zastanawiam się nad architekturą obiektu. Mniej więcej wygląda to tak:
jest aplikacja www która budową przypomina jakiekolwiek z brzegu wzięte środowisko social ( użytkownicy posiadający konta, dane, galerie, artykuły etc). Działanie aplikacji przebiega tak:

  1. Użytkownik loguje się pierwszy raz
  2. Kontroler stosu ( zawiera tablice obiektów użytkowników ) sprawdza czy posiada danego pacjenta na stosie
    2a. jeśli tak, zwraca mu jego obiekt ze stosu
    2b. jeśli nie, tworzy obiekt, wsadza na stos i zwraca pacjentowi
  3. pacjent jest zadowolony i śmiga
  4. każdy kolejny request ( przeładowanie strony ) powtarza się od punktu 2 ( stos -> sprawdź czy masz mój obiekt -> zwróć )

Nic skomplikowanego .. ot prosta aplikacja.
Do rzeczy.
Jest kilka miejsc w których pacjent korzysta z bazy ( nie ważne co pobiera ). Na chwilę obecną w przypadku potrzeby zassania z bazy, pacjent pobiera sobie instancje połączenia z bazą z singletona ( klasa do obsługi bazy jest singletonem ). I wszystko ok. Ale natknęła mnie myśl czy może nie lepszym rozwiązaniem ( skoro każdy z użytkowników posiada własny obiekt ) byłoby stworzenie dla każdego z nich osobnego obiektu dla połączeń z bazą który także byłby trzymany w jego obiekcie.

Skąd taka myśl ?

  1. serwer DB jest przysłowiowym "Deep blue" - 128 GB ramu, jakieś procesory nie z tej planety .. wydajnością bazy martwić się nie muszę jak i ilością jednoczesnych połączeń
  2. mogą być momenty kiedy jednocześnie działa około 400 użytkowników - na tym jednym biednym singletonie
  3. ... pierwszy raz robię sajt jako aplikacje .net stąd tego typu historie są jeszcze troszkę mi obce

Sugestie mile widziane.

PS. przesiadka z PHP na c# jest szokiem termicznym ... zgodności typów zachowane i od razu porządek w kodzie ;)

pozdrawiam

0

connection do bazy jako singleton dla wielu uzytkownikow to nieporozumienie!
chyba ze w kodzie zadbales o synchronizacje dostepu i czemu nie? :D

wiec jednak jesli juz to pomysl z obiektem connection per user jest duzo lepszy
jednak jesli to aplikacja web to jednak proponuje tworzyc polaczenie dla kazdej strony po uzyciu zamykasz i tyle (np. w init opwierasz, a w prerender zamykasz)
zostawianie otwartych connection przy duzej liczbie userow i dlugim czasie sesji nie bedzie dobrym rozwizaniem
mozesz oczywiscie miec jeden obiekt connection per user i robic jego open-close jak trzeba, ale to wlasciwie nie rozni sie od tworzenia nowego connection
przy wydajnych werwerach web i db oraz szybkim polaczeniu miedzy nimi nawet nie zauwazysz narzutu (wiem co mowie bo tak robilem)

0

Pomysł z init i prerender godny uwagi ale muszę przeanalizować ile procentowo requestów wymaga połączenia ... bo jeśli jest to poniżej 40% to chyba zdecyduje się na opcję per user.

W każdym razie dzięki za podpowiedź ... co dwie czaszki to nie jedna ;)

0

Moim zdaniem najlepiej każdą operację/transakcję zamykać w blok

using (var conn = new SqlConnection....)
{
.....
}

Połączenie jest wówczas tworzone tylko wtedy, gdy jest potrzebne i nie pozostawiasz niechący brudu.
Po wyjściu z bloku sprzątany jest jedynie obiekt SqlConnection, ale fizyczne połączenie do bazy jest jakiś czas utrzymywane. .NET jest na tyle mądry, że sam zarządza swoją pulą połączeń na "niższym poziomie" tak, aby dla każdego żądania nie było tworzone nowe tylko wykorzystuje te, które są już otwarte i wolne.

0

Dokladnie tak jak powiedzial procento :)
DeeCann, nie musisz martwic sie takimi rzeczami i poczytaj o connection pooling :) Conajwyzej by zoptymalizowac to na wieksza ilosc userow musisz odpowiednie parametry w connection stringu poustawiac i to wszystko :)

0

Super ... fajnie, schludnie i przyjemnie. Dzięki.
Zacząłem także czytać o connection pooling i znalazłem o to coś takiego:
Do not call Close or Dispose on a Connection, a DataReader, or any other managed object in the Finalize method of your class. In a finalizer, only release unmanaged resources that your class owns directly. If your class does not own any unmanaged resources, do not include a Finalize method in your class definition. For more information, see Garbage Collection.

Nie wiem za bardzo jak to rozumieć bo słowo w słowo, to finalize zwalnia nieużywane zasoby z danej klasy, a zauważyłem, że zdarza mi się używać bloku try/catch/finalize gdzie w finalize zamyka SqlReader'a i czasem SqlConnection.

Ale faktycznie tak jak procento napisał using() jest fajnym rozwiązaniem

pozdrawiam

0

Mylisz metodę "Finalize()" z blokiem "finally". Finelize() to sposób na napisanie destruktora w C# (więcej tutaj: Object.Finalize Method ), zaś finally służy właśnie do tego do czego go używasz - wykonywania operacji takich jak zwalnianie zasobów niezależnie od wystąpienia wyjątku.

0

Czytanie ze zrozumieniem ... było coś takiego na j.polskim :P

0

(np. w init opwierasz, a w prerender zamykasz)

Fatalny pomysł. Pogrzeb MVC.

using (var conn = new SqlConnection....)
{
.....
}

.. jedyny słuszny pomysł :)

Nie wiem za bardzo jak to rozumieć bo słowo w słowo, to finalize zwalnia nieużywane zasoby z danej klasy, a zauważyłem, że zdarza mi się używać bloku try/catch/finalize gdzie w finalize zamyka SqlReader'a i czasem SqlConnection.

To co poprzednik napisał, plus - Garbage Collector

Opisuje nie tylko to co w temacie, ale wyjaśnia czym są Finalizery.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.