Krótko:
- Zawsze używaj transakcji
- Nie używaj
Close()
, zamiast tego zawijaj wywołania w instrukcji ISession
wewnętrznej using
lub zarządzaj cyklem życia swojej ISession w innym miejscu .
Z dokumentacji :
Od czasu do czasu ISession
będzie wykonywał instrukcje SQL potrzebne do synchronizacji stanu połączenia ADO.NET ze stanem obiektów przechowywanych w pamięci. Ten proces, opróżnianie, występuje domyślnie w następujących punktach
- z niektórych wywołań
Find()
orEnumerable()
- z
NHibernate.ITransaction.Commit()
- z
ISession.Flush()
Instrukcje SQL są wydawane w następującej kolejności
- wszystkie wstawienia elementów, w tej samej kolejności, przy użyciu którego zostały zapisane odpowiednie obiekty
ISession.Save()
- wszystkie aktualizacje encji
- wszystkie usunięcia kolekcji
- wszystkie usunięcia, aktualizacje i wstawienia elementów kolekcji
- wszystkie wstawki do kolekcji
- wszystkie usunięcia jednostek w tej samej kolejności, w których odpowiadające im obiekty zostały usunięte za pomocą
ISession.Delete()
(Wyjątkiem jest to, że obiekty korzystające z natywnego generowania identyfikatorów są wstawiane podczas zapisywania).
Z wyjątkiem sytuacji, gdy jest to jednoznaczne Flush()
, nie ma absolutnie żadnych gwarancji, kiedy sesja wykona wywołania ADO.NET, a jedynie kolejność, w jakiej są wykonywane . Jednak NHibernate gwarantuje, że ISession.Find(..)
metody nigdy nie zwrócą nieaktualnych danych; ani nie zwrócą niewłaściwych danych.
Można zmienić domyślne zachowanie, aby spłukiwanie występowało rzadziej. FlushMode
Klasa definiuje trzy różne tryby: przemywać tylko popełnić czasu (i tylko wtedy, gdy NHibernate ITransaction
jest używane API), równo automatycznie za pomocą wyjaśnił rutyna, albo nigdy równo chyba Flush()
nazywa się jawnie. Ostatni tryb jest przydatny w przypadku długo działających jednostek pracy, w których jest ISession
on otwarty i odłączony przez długi czas.
...
Zapoznaj się również z tą sekcją :
Zakończenie sesji obejmuje cztery różne fazy:
- opróżnij sesję
- zatwierdzić transakcję
- zamknij sesję
- obsługi wyjątków
Opróżnianie sesji
Jeśli korzystasz z ITransaction
interfejsu API, nie musisz się martwić o ten krok. Zostanie wykonany niejawnie, gdy transakcja zostanie zatwierdzona. W przeciwnym razie należy zadzwonić, ISession.Flush()
aby upewnić się, że wszystkie zmiany są zsynchronizowane z bazą danych.
Zatwierdzenie transakcji bazy danych
Jeśli używasz NHibernate ITransaction API, wygląda to tak:
tx.Commit();
Jeśli samodzielnie zarządzasz transakcjami ADO.NET, należy ręcznie Commit()
wykonać transakcję ADO.NET.
sess.Flush();
currentTransaction.Commit();
Jeśli zdecydujesz się nie zatwierdzać zmian:
tx.Rollback();
lub:
currentTransaction.Rollback();
Jeśli wycofasz transakcję, powinieneś natychmiast zamknąć i odrzucić bieżącą sesję, aby upewnić się, że stan wewnętrzny NHibernate jest spójny.
Zamknięcie ISession
Wezwanie do ISession.Close()
oznaczenia końca sesji. Główną konsekwencją metody Close () jest to, że połączenie ADO.NET zostanie porzucone przez sesję.
tx.Commit();
sess.Close();
sess.Flush();
currentTransaction.Commit();
sess.Close();
Jeśli podałeś własne połączenie, Close()
zwraca do niego odwołanie, aby można było je ręcznie zamknąć lub zwrócić do puli. W przeciwnym razie Close()
zwraca go do puli.
Począwszy od NHibernate 2.0 transakcje są wymagane do operacji DB. Dlatego
ITransaction.Commit()
wywołanie zajmie się każdym koniecznym spłukiwaniem. Jeśli z jakiegoś powodu nie korzystasz z transakcji NHibernate, automatyczne opróżnianie sesji nie będzie możliwe.źródło
Od czasu do czasu ISession będzie wykonywał instrukcje SQL potrzebne do synchronizacji stanu połączenia ADO.NET ze stanem obiektów przechowywanych w pamięci.
I zawsze używaj
using (var transaction = session.BeginTransaction()) { transaction.Commit(); }
po zatwierdzeniu zmian niż te zmiany do zapisania w bazie danych używamy transaction.Commit ();
źródło
Oto dwa przykłady mojego kodu, w których nie udałoby się to bez sesji.Flush ():
http://www.lucidcoding.blogspot.co.uk/2012/05/changing-type-of-entity-persistence.html
na końcu możesz zobaczyć sekcję kodu, w której włączam wstawianie tożsamości, zapisuję jednostkę, a następnie opróżniam, a następnie wyłączam wstawianie tożsamości. Bez tego spłukiwania wydawało się, że włącza i wyłącza wstawianie tożsamości, a następnie zapisuje jednostkę.
Użycie Flush () dało mi większą kontrolę nad tym, co się dzieje.
Oto kolejny przykład:
Wysyłanie wiadomości NServiceBus wewnątrz TransactionScope
Nie do końca rozumiem, dlaczego w tym przypadku, ale Flush () zapobiegła wystąpieniu mojego błędu.
źródło