2009-04-23 14 views
6

Uznałem, że nie było możliwe uzyskanie przecieku połączenia sql podczas korzystania z LINQ, ale śledzenie śledzenia funkcji NumberOfReclaimedConnections pokazuje dużą liczbę i przy dużym obciążeniu czasami występują wyjątki, takie jak "Upłynął limit czasu." Limit czasu upłynął przed uzyskaniem połączenia od Może się tak zdarzyć, ponieważ wszystkie połączone połączenia były w użyciu i został osiągnięty maksymalny rozmiar puli ".Czy można uzyskać przecieki połączenia sql za pomocą LINQ?

Nie używamy Dispose w datacontext, ponieważ użyliśmy odroczonego ładowania. Kilka artykułów i blogów mówi mi, że nie powinno to stanowić problemu.

Wciąż dostaję te wyjątki. Ale nie może być tak, że każde zapytanie linq, które pozostawi otwarte połączenie, będzie miało znacznie więcej wyjątków.

Edytowane

Aplikacja jest usługą WCF.

Jeśli przyjrzeć się dokumentacji Linq i większości artykułów, twierdzą oni, że usunięcie nie jest konieczne do zwolnienia połączeń. Twierdzą, że DataCOntext utrzymuje połączenie otwarte tylko przez krótki czas, kiedy jest to potrzebne.

Odpowiedz

8

Gdy twoje DataContext nie zostanie wyrzucone i pozostanie przy życiu, powiązane połączenie pozostanie przy życiu. Połączenia z bazą danych są niezarządzanymi zasobami, a wszystkie zasoby niezarządzane muszą być odpowiednio usuwane.

Nawet jeśli używasz opóźnienia i nie masz dobrze zdefiniowanego zakresu, nadal powinieneś wyczyścić połączenia z bazą danych na końcu logicznej jednostki pracy. W aplikacjach ASP.NET najpóźniejszym możliwym momentem jest zakończenie przetwarzania żądania - w metodzie Application_EndRequest pliku Globals.asax. W usłudze WCF każdy aktywny kontekst danych powinien zostać usunięty na końcu każdego wywołania metody usługi.

Dokumentacja tego jest nieprecyzyjna i chociaż przez większość czasu można się pozbyć nie wyrzucania DataContext, wydaje się, że istnieją pewne scenariusze, w których dane ładowane z połączenia utrzymują połączenie przy życiu. Najprostszym sposobem potwierdzenia, że ​​tak się dzieje w twoim przypadku, jest przetestowanie go.

+0

Niezły dodatek. Dzięki :) –

0

Czy masz jakieś zakleszczenia w swojej bazie danych? Szybkie spojrzenie na monitor aktywności powinno dać ci pewne wskazówki.

Co robisz, aby zarządzać cyklem życia DataContext - jaki rodzaj aplikacji napisałeś (strona internetowa, klient systemu Windows, inne)?

Po zastosowaniu w zapytaniu lub operacji, DataContext będzie utrzymywał połączenie, aby załadowane jednostki mogły leniwie ładować & itd., Dlatego konieczne jest zaplanowanie sposobu korzystania z DataContexts w aplikacji.

Usługi WCF. W tym przypadku jestem wielkim fanem podejścia "jeden kontekst na żądanie". Zachęcam do otakowania operacji na danych w instrukcji using(), aby kontekst został usunięty, gdy skończysz.

+0

Nie mamy żadnych problemów z zakleszczeniami, przynajmniej nie ja, o ile wiem na razie, i monitorujemy to. Aplikacja to usługi WCF, a format danych nie powinien nigdy trwać dłużej niż połączenie serwisowe. – Atle

4

znalazłem po kilka poszukiwania znalazłem ten question and answer, gdzie jest napisane, że LINQ można nabrać do opuszczenia połączenia otwarte ..

Zrobiłem ten mały kod testowy, który odtwarza go. Jeśli po prostu zamienię Enumerator na foreach, działa dobrze, ale Enumerator utrzymuje połączenia otwarte.

public Organisation RunTestQuery2() 
{ 
    IEnumerable<Organisation> orgs = base.GetEntities<Organisation>().Take(5); 

    var enumerator = orgs.GetEnumerator(); 
    int i = 0; 


    while (enumerator.MoveNext()) 
    { 
     var org = enumerator.Current; 
     Debug.WriteLine(org.DescribingName); 
     if (i == 3) 
     { 
      return org; 
     } 
     i++; 
    } 

    return null; 
} 

Jeśli dodaję wezwanie do usunięcia kontekstu, znikają.

+0

To tylko magia kompilatora. foreach jest składnią candy do tworzenia instancji Enumerator, wywoływanie MoveNext, aż zwróci false, a następnie wywołanie Dispose na Enumerator. Po prostu dla FYI. – Kilanash

Powiązane problemy