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.