Archiwum

Archive for the ‘Bazy danych’ Category

Entity Framework i wstrzykiwanie otwartego połączenia–czyli wyjaśniamy czym jest Connection Polling I jak sobie z nim radzić

Sierpień 5, 2013 Dodaj komentarz

Odkrywam kawałek tajemnicy dla osób, które zamierzają tworzyć strony internetowe używane przez tysiące…. jednym z wąskich gardeł jest Baza Danych… sic! Nie będę się tu wdawał w kwestie budowania architektury, dobrej I złej. Bardziej chciałbym naświetlić pewien problem I możliwe rozwiązanie.

Bazy danych w .NET Framework w większości (zakładam, że 99% przypadków), są obsługiwane przez mechanizm ADO.NET, a ten bazuje na ConnectionString do źródła danych, który jest zdefiniowany według wzoru zgodnego z bazą do której się łączymy. Różne wzory znajdziemy tutaj – http://www.connectionstrings.com/

Różne bazy, różne wymagania, ale jednym stałym punktem jest tak zwany Connection Pooling… o których jak się okazuje niewiele osób wie.

Connection Pooling to mechanizm, który pozwala zachować (cache’ować) otwarte połączenia do bazy danych by móc je wykorzystać ponownie podczas kolejnych zapytań bez potrzeby otwierania nowych kanałów do serwera. Niewiele osób wie, że jak nie zdefiniujemy nic sami, to standardowo mechanizm jest włączony I ma limit do 100 połączeń.
Jeżeli aplikacja wykorzystuje w jednym momencie 100 połączeń do bazy (wykonuje 100 zapytań)… I próbuje otworzyć 101 to po odczekaniu odpowiedniego czasu (timeout) otrzymamy Exception. Nie jest to ciekawe…. dodatkowo mało deterministyczne, jakby to powiedział programista “U mnie działa”.

W jednym z projektów jakie ostatnio widziałem była dość ciekawa pętla, która potrafiła otworzyć kilka…dziesiąt połączeń per użytkownik, per request. Panic mode pełną parą.

Rozwiązanie tego bez znaczącej zmiany logiki wyglądało tak, że użytkownik przychodzący na serwer z swoim requestem otrzymywał jedno połączenie do bazy I to połączenie wykorzystywał do dostępów wszystkich metodach jakie wywoływał na bazie aż do zakończenia renderowania widoku.

We wszystkim tutaj pomogło użyte w projekcie Entity Framework.Standardowo kiedy tworzymy nowy Context bazy w sekcji using połączenie jest otwierane I zamykane wraz z skończeniem zapytania (sekcji using). Ciekawą funkcjonalność ma tutaj EntityFramework, która pozwala sobie wstrzyknąć otwarte połączenie (DbConnection) do konstruktora, a ten w momencie zakończenia sekcji using nie zamknie połączenia, tylko zostawi je otwarte.

Działa tutaj prosta zasada… jak Context ma wykonać zapytanie to tworzy, otwiera I zamyka połączenie. Jak ktoś mu dał jednak połączenie, to po prostu z niego korzysta, nie ubija, nie zamyka – super!