2010-01-06 23 views
41

Jestem nowy w NHibernate i widziałem pewne problemy podczas zamykania sesji przedwcześnie. Rozwiązałem to tymczasowo przez ponowne użycie sesji zamiast otwierania sesji dla transakcji. Miałem jednak wrażenie, że sesje otwierające za każdym razem, gdy ich potrzebujesz, były zalecanym podejściem do zarządzania sesją w ciągu całego życia. Nie?Jaki powinien być czas trwania sesji NHibernate?

Tak; jaki jest zalecany sposób obsługi sesji? Jakie powinno być ich życie? Transakcja jednej sesji? Jedna sesja singleton do obsługi wszystkiego? Albo co?

Edit:

Zauważ, że moja architektura aplikacji jest aplikacja komunikuje się z usługą po stronie serwera, który jest, co czyni całą obsługę bazy danych, używając NHibernate + biegle. (Jeśli to robi różnicę ...)

+2

W pytaniu http://stackoverflow.com/questions/2011950/nhibernate-mappings-issue-when-referencing-class-lazy-load-issue poprosiłeś mnie, żebym zagłębił się w to nowe pytanie, ale widzę cię " Już otrzymałem duży zasięg. Wymieniam niektóre opinie tutaj, ale należy pamiętać, że sesje i transakcje są wymieszane w dyskusji, podczas gdy te są różne. Pula sesji lub sesja wyzwalana limitem czasu może być korzystna pod względem wydajności, ale trudna do skonfigurowania i poprawienia. Należy również pamiętać, że pod maską, łączenie połączeń jest używane niezależnie od wybranego wzorca. – Abel

+0

Dzięki za komentarz Abel. W przykładach, które widziałem, sesje i transakcje często mają ten sam czas życia, ale jak widać w zadawanym pytaniu, może to być czasem problem. Mam nadzieję, że ludzie odpowiedzieli na "okres życia sesji" - nie "czas trwania transakcji", jestem pod wrażenie, że tak jest. – stiank81

Odpowiedz

26

Potrzebujesz strategii zarządzania sesją, która pozwoli Twojej aplikacji działać efektywnie i korzystać z rzeczy, które oferuje NHibernate - w szczególności pamięci podręcznej i leniwego ładowania.

Tworzenie sesji jest procesem niedrogim i wymaga niewielkiej pamięci RAM lub procesora, więc nie powinieneś się martwić o konserwację lub ponowne używanie sesji (w rzeczywistości ponowne ich użycie może prowadzić do nieprzyjemnej i nieprzewidzianej strony -ruchomości). Fabryka sesji jest kosztowną rzeczą i powinna zostać zbudowana tylko raz podczas uruchamiania aplikacji.

Zasada jest taka: czas życia sesji musi być wystarczająco długi, aby nie utracić trwałych obiektów w zasięgu po zakończeniu sesji.

Po zakończeniu sesji wszystkie śledzenie zmian dla obiektów otrzymanych z tej sesji zatrzymuje się, więc zmiany te nie zostaną zapisane, chyba że celowo ponownie przyłączysz ten obiekt do nowej sesji. Sesja powinna zatem trwać tak długo, jak długo będą pobierane obiekty z niej pobierane. W aplikacji internetowej oznacza to zwykle sesję dla każdego żądania; w WinForms: sesja dla każdego formularza.

W twoim przypadku, z usługą (zakładam, że to działa jak usługa Windows) robi pracę NHibernate, można rozważyć posiadające sesji tworzony dla każdego nowego wniosku od spożywającej aplikacji komputerowej i usuwania go kiedy to żądanie zostało obsłużone. Nie wiesz dokładnie, jak działa twoja usługa i jaki mechanizm używa aplikacja komputerowa, aby z nią rozmawiać (remoting? WCF? Zwykły stary SOAP?) Nie mogę być bardziej konkretny.

(Istnieje kilka wyjątków od tej ogólnej zasady - załóżmy, że masz zestaw utrwalonych obiektów, które reprezentują wspólny zasób, do którego odnoszą się inne kody, ale nie zmieniają się, możesz załadować je z góry przy uruchamianiu aplikacji i opuścić Odłączono je od tego momentu.)

Jeśli wydajność jest powolna zgodnie z taką strategią, może to oznaczać, że po prostu rozmawiasz z bazą danych za dużo, a wykres obiektów jest złożony; spójrz na second-level caching w tym przypadku.

+0

Dzięki!Jeśli chodzi o moją usługę, używam WCF, obecnie z mydłem - działającym jako aplikacja konsolowa, ale nie sądzę, żeby to miało jakieś znaczenie, więc byłeś wystarczająco konkretny. Brzmi rozsądnie, aby mieć jedną sesję dla każdego żądania. Obecnie używam tylko sesji, w której uruchamiana jest transakcja, i wydaje się, że istnieją pewne dane referencyjne, które nie są ładowane podczas transakcji, która nie powiedzie się, ponieważ sesja została zamknięta. – stiank81

6

Sesja powinna odpowiadać jednostce pracy. Sesja powinna pozostać przy życiu podczas pracy z obiektami pobranymi lub utrzymywanymi przy użyciu tej sesji.

0

Znaczna część struktury NHibernate i Microsoft ADO.NET Entity Framework są podobne. Oto bardzo dobry artykuł na temat tego, jak kontrolować linię życia ObjectContext w ADO.NET EF.

http://blogs.msdn.com/alexj/archive/2009/05/07/tip-18-how-to-decide-on-a-lifetime-for-your-objectcontext.aspx

Należy zastosować do sesji NHibernate, jak również.

+1

Moim zdaniem, ponieważ EF 1.0/3.5 nie obsługuje automatycznego ładowania opartego na proxy, różnice między EF i NHibernate w odniesieniu do tego problemu są zbyt duże, aby skutecznie dzielić się poradą. Życiorys ObjectContext w EF jest łatwiejszy w zarządzaniu, ponieważ EF nie jest tak bogaty w funkcje. –

+0

Masz rację, że EF 1.0 tego nie obsługuje, ale EF 2.0 to robi. Ten artykuł wydaje się mieć zastosowanie do obu. –

11

W aplikacji internetowej powinna istnieć jedna sesja na żądanie. Zapewnia to pełną kontrolę nad czasem życia sesji i upraszcza obsługę błędów.

W aplikacji komputerowej polecam korzystanie z sesji na jednego prezentera (lub formularza, jeśli wolisz). Zacytować Ayende w Jego MSDN Magazine article:

Zalecana praktyka dla pulpitu aplikacji jest użycie sesji za formie, tak, że każda forma we wniosku ma swoją własną sesję. Każdy formularz zwykle stanowi odrębną pracę, którą użytkownik chciałby wykonać, aby użytkownik wykonał operację , co w praktyce bardzo dobrze pasuje do cyklu życia sesji . Dodatkową korzyścią jest to, że nie masz już problemu z wyciekami pamięci, ponieważ po zamknięciu formularza w aplikacji możesz także zutylizować sesję . Spowoduje to, że wszystkie jednostki , które zostały załadowane przez sesję , kwalifikują się do rekultywacji przez odśmiecenie (GC) przez .

Istnieją dodatkowe powody, dla których preferuje pojedynczą sesję na formularz. Możesz skorzystać ze śledzenia zmian NHibernate , więc spowoduje to przeprojektowanie wszystkich zmian w bazie danych po zatwierdzeniu transakcji przez użytkownika .To również tworzy barierę izolacyjną pomiędzy różnych formach, dzięki czemu można popełnić zmiany do jednego podmiotu bez martwienia się o zmianach wprowadzonych do innych podmiotów, które są wyświetlane na innych formach.

+0

"sesja na operację" jest raczej niejasna. Powinieneś wspomnieć "sesja na żądanie" –

Powiązane problemy