2012-03-03 12 views
9

Jestem tak zdezorientowany sesjami i transakcjami. Zasadniczo nie widzę, jaki jest cel posiadania obu, i jestem bardzo zdezorientowany, kiedy użyć jednego lub drugiego.Grails: Jaka jest różnica między sesją niezamkniętą i wycofaną?

Jaka jest różnica między sesją niezamkniętą a niezakończoną?

Nie wiem nawet, jak zapytać o to, czego nie wiem ... czy istnieje zasób dający dobre przykłady typowych sytuacji sesji i transakcji, więc widzę różnicę?

Odpowiedz

18

Transakcja w Hibernate jest prawie taka sama jak transakcja w JDBC w ogóle. Po uzyskaniu Connection z DataSource domyślnie jest autocommit = true, więc dla transakcji, która została zmieniona na autocommit = false. W ten sposób zmiany są wprowadzane w bazie danych tylko wtedy, gdy są jawnie zatwierdzane zamiast za każdym razem, gdy robisz aktualizację.

Hibernate ma Session robi kilka rzeczy, ale w tym przypadku jego funkcja jest jak cache pierwszego poziomu. Wykorzystuje on koncepcję zwaną "transakcyjną writebehind" dla wydajności, aby umieścić w kolejce zmiany w tej pamięci podręcznej i w razie potrzeby przenosić je do bazy danych. Na przykład, jeśli pobierzesz trwałą instancję i zmienisz ją w złożonym procesie pracy opartym na wielu metodach, w którym każda metoda może nie dokonać żadnych zmian lub kilku, potrzebna jest tylko jedna instrukcja SQL aktualizacji, więc Hibernate czeka, aż konieczne będzie ich połączenie. Jest to niezależne od tego, czy korzystasz z transakcji - zawsze tak się dzieje.

Miejsce, w którym pamięć podręczna sesji i aktywna transakcja się łączą, przepłukuje podczas aktywnej transakcji. Ponieważ Hibernate czeka tak długo, jak to możliwe, aby wypróżnić zmiany, jeśli nie jesteś w transakcji i spłukujesz, zmiany stają się trwałe w bazie danych natychmiast. Jest to optymalizacja wydajności w celu zmniejszenia liczby zapisów w bazie danych. Ale jeśli jesteś w transakcji i opróżniasz sesję, wprowadzasz zmiany do bazy danych. Ale baza danych przechowuje zmiany w swojej kolejce transakcji. Więc nawet jeśli są w bazie danych, nie są widoczne dla innych połączeń, dopóki nie zatwierdzisz transakcji.

Idealnie nie będzie żadnych wyraźnych spłukań, a zatwierdzenie transakcji wywoła spłukiwanie przed zatwierdzeniem, co zminimalizuje liczbę koniecznych do przejścia do bazy danych i pozostawi niezatwierdzone zmiany niewidoczne dla innych rozmówców. Ale możesz spłukać tyle razy, ile potrzebujesz.

Jedną z rzeczy, która spowoduje automatyczne opróżnienie Hibernate w twoim imieniu, są zapytania. Jak już powiedziałem, możesz wprowadzić wiele zmian w trwałych instancjach (nawet je kasując), a one będą po prostu umieszczane w kolejce w pamięci podręcznej sesji. Ale jeśli uruchomisz zapytanie (dynamiczny odnośnik, kryteria, HQL itd.), Hibernate nie będzie wiedział, czy zmiany w kolejce wpłyną na twoje zapytanie. Jest więc pesymistyczny i spieka, aby mieć pewność, że wszystko jest spójne dla zapytania. Baza danych użyje danych spłukiwanych, ale nie zatwierdzonych dla Twojego zapytania i zwróci oczekiwane wyniki. Z tego powodu zalecamy stosowanie metody withNewSession podczas wykonywania kwerend w niestandardowych weryfikatorach klasy domeny, aby podczas sprawdzania poprawności nie powodowały one przepełnienia bieżącej sesji, co może powodować dziwne zachowanie.

Powiązane problemy