2012-05-10 19 views
5

A mam akcję na mojej aplikacji MVC, która ma id i zwraca nazwisko osoby.NHibernate - najlepsza praktyka do wybrania tylko

Jaka jest najlepsza praktyka? Śledzę wskazówki NHProf, ale kod brzmi trochę dziwnie lub coś dla mnie.

using (var session = Helper.SessionFactory.OpenStatelessSession()) 
{ 
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted)) 
    { 
     return session.Query<Person>().Where(x => x.Id == id).Select(x => x.Name).SingleOrDefault(); 
     tran.Rollback(); 
    } 
} 
+0

nie mogę zrozumieć, dlaczego to sugerować transakcję ... –

+0

co chcesz wiedzieć? –

+1

Nie użyłbym 'OpenStatelessSession' sesję bezstanową dla scenariuszy masowych i ignoruje pamięć podręczną L1. Zamiast wykonywać kwerendę linq, po prostu wywoływam '.Load (1)' lub '.Get (1)' który wyraża zamiar więcej niż zapytania linq. – Andreas

Odpowiedz

4

Strona alert NHProf wyjaśnia to całkiem dobrze myślę -

http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

Zasadniczo to mówiąc, jeśli nie zarządzania transakcjami siebie, baza danych będzie stworzenie „niejawny transakcji” i auto -komenda dla każde oświadczenie, w tym zapytania. Błędem jest to, że transakcje są użyteczne tylko w przypadku operacji wstawiania/aktualizacji.

W powyższym przykładzie nie stanowi to większego problemu, ponieważ transakcja wykonuje i tak tylko jedną instrukcję. Jeśli twoja metoda zawierała kilka instrukcji, dobrze byłoby zawinąć je w transakcję.

+0

OK, ale w przypadku prostych metod należy postępować zgodnie z NHProf i utworzyć transakcję, czy nie? – Zote

+1

Odpowiedź jest tylko częściowa, powinieneś __always__ wypaczyć zapytanie bazy danych w transakcji i rzeczywiście byłby to problem, nawet jeśli wykonasz pojedynczą instrukcję. Niejawne transakcje są drogie! i NH nie użyje pamięci podręcznej L2 bez transakcji. – Andreas

-1

Poniżej jak bym podejść do tego select:

using (var session = Helper.SessionFactory.OpenStatelessSession()) 
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted)) 
    { 
     try 
     { 
      string personName = session.Query<Person>() 
      .Where(x => x.Id == id) 
      .Single(x => x.Name); 

      tran.Commit(); 
      return personName; 
     } 
     catch(Exception ex) 
     { 
      // handle exception 
      tran.Rollback(); 
     } 
    } 

Ten SO odpowiedź daje dobre rady do czynienia z transakcją zobowiązuje:

NHibernate - Is ITransaction.Commit really necessary?

W odniesieniu do swojej LINQ to jest ciekawy artykuł o tym, jak nie przystępować do zapytań przy użyciu składni stylu metody rozszerzenia:

http://compiledexperience.com/blog/posts/how-not-to-use-linq

+0

-1 za złapanie wszystkiego, wykonanie zbędnej pracy (użycie i próba złapania). – Andreas

+0

@Andreas, o ile wiem, nie ma możliwości przetwarzania wyrzuconego wyjątku, a wybór polega na użyciu zbędnej próby lub ręcznego wyrzucenia. Również w jaki sposób można wdrożyć obsługę błędów w tym przypadku, ponieważ istnieje wiele warstw, które mogą rzucić błąd (NHibernate, ADO.NET, LINQ). –

+2

http://stackoverflow.com/questions/6418992/is-it-a-better-practice-to-explicitly-call-transaction-rollback-lub-let-an-except i dla wyjątków http://stackoverflow.com/questions/426346/is-this-a-bad-practice-to-catch-a-non-specific-exception-as-system-exceptio http://stackoverflow.com/questions/114658/catching-base- wyjątek-klasa-w-sieci http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx i nie mów mi, że możesz poprawnie obsłużyć stackoverflows, out of memory exc z twoim 'tran.Rollback();'. – Andreas

0

Nie twórz wielu sesji na jedno żądanie HTTP, najlepiej, co musisz zrobić, to otworzyć sesję i odpowiednią transakcję w zasięgu żądania i używać tej sesji do wszystkich swoich działań.

Oto blogpost wyjaśniając jak to osiągnąć: http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx

Sugerowałbym użycie kontenera IOC i utworzyć klasę, która tworzy sesję dla ciebie i zakresu tej klasy do zakresu żądania.

Istnieje wiele zasobów w internecie, aby podejść do tego problemu .. Google to ..

+0

Podczas jednej sesji na żądanie jest dobra rada, nie jest to reguła twarda i szybka, a posiadanie jednej transakcji na jedno żądanie jest złą radą, prostą i prostą. – Spivonious

Powiązane problemy