2012-05-10 16 views
7

Mam pewne problemy ze zrozumieniem, skąd zapytanie HQL pobiera informacje. Mój projekt używa różnych wątków i każdy wątek czyta/zapisuje do bazy danych. Wątki nie współużytkują obiektów sesji, zamiast tego używam klasy HibernateUtil, która tworzy dla mnie sesje.Hibernate HQL trafia tylko pamięć podręczną sesji

Do niedawna zamykałem sesję dopiero po napisaniu, ale nie po lekturze. Zmiany w obiektach byłyby natychmiast widoczne w bazie danych , ale podczas czytania na innych wątkach (inny obiekt sesji niż ten używany do pisania) Otrzymałbym nieaktualne informacje. Czytanie i pisanie odbywało się zawsze na różnych wątkach, co oznacza różne obiekty sesji i różne pamięci podręczne sesji.

Zawsze myślałem, że za pomocą HQL zamiast Criteria, bym zawsze kierować do bazy danych (lub drugą pamięć podręczną poziomu), a nie pamięci podręcznej sesji, ale podczas debugowania kodu, to było robione dla mnie jasne, że HQL szukał obiekt w pamięci podręcznej sesji i pobrany stary przestarzały obiekt.

Czy myliłem się przyjmując, że HQL zawsze jest kierowane do bazy danych? A przynajmniej pamięć podręczna drugiego poziomu?

PS: Używam tylko jednego obiektu SessionFactory.

Odpowiedz

7

Hibernacja ma różne koncepcje buforowania - bufory encji i bufory zapytań. Buforowanie jednostek jest tym, co robi pamięć podręczna sesji (i pamięć podręczna drugiego poziomu, jeśli jest włączona).

Zakładając, że buforowanie zapytań nie jest włączone (co nie jest domyślnie), to Twój HQL zostałby wykonany na bazie danych. To by zwróciło identyfikatory jednostek pasujących do zapytania. Jeśli te jednostki były już w pamięci podręcznej sesji, Hibernacja zwróciłaby je, zamiast przebudowywać je z bazy danych. Jeśli twoja sesja ma nieaktualne kopie (ponieważ inna sesja zaktualizowała bazę danych), to masz taki problem.

Odradzam korzystanie z długotrwałych sesji, głównie z tego powodu. Należy ograniczyć czas trwania sesji do określonej jednostki pracy, którą próbujesz wykonać, a następnie ją zamknąć. W tym celu nie ma kary za wydajność (zakładając, że korzystasz z puli połączeń z bazą danych). Ewentualnie, aby upewnić się, że nie otrzymasz nieaktualnych elementów, możesz zadzwonić pod numer Session.clear(), ale możesz otrzymać nieoczekiwane efekty uboczne wydajności.

+0

więc po raz pierwszy mój obiekt sesji wykonuje kwerendę HQL, która jest kierowana do bazy danych. wynik jest następnie przechowywany w pamięci podręcznej sesji. po raz drugi wykonuję tę samą kwerendę HQL, odczytuje pamięć podręczną zamiast kierowania na bazę danych. to jest domyślne zachowanie. czy zrozumiałem to poprawnie? ** ps: ** Rzeczywiście, zamykanie sesji po każdym odczytaniu i zapisaniu (krótkotrwałe obiekty 'Session') rozwiązuje mój problem. – alegen

+4

@alegen: HQL będzie uruchamiany w bazie danych * za każdym razem *, ale obiekty Java, które są wynikiem końcowym tego zapytania, mogą pochodzić z pamięci podręcznej sesji. To jest domyślne zachowanie. – skaffman

+1

, proszę pana, życzę miłego dnia! Dziękuję Ci za Twoje odpowiedzi :) – alegen

Powiązane problemy