2012-04-03 8 views
7

Zwykle używam wzorzec zarządzania sesji Hibernate ThreadLocal w projektach internetowych Java:Hibernate ThreadLocal Session Management zgodny z ForkJoinPool?

wątku lokalny wzorzec Session wykorzystuje java.lang.ThreadLocal klasy do utworzenia sesji, który jest dostępny z jednej aplikacji wątek. Jest to szczególnie wygodne w aplikacjach wielowątkowych, takich jak aplikacje internetowe.

W projektach zaimplementować to z

<property name="current_session_context_class">thread</property> 

w hibernate.xml i korzystania SessionFactory.getCurrentSession() dostać sesję ilekroć potrzebujesz.

Teraz mam program, który jest nie serwlet, ale nie ciężkie przetwarzania równoległego i interakcji bazy danych.

Chcę to zaimplementować z ForkJoinPool. Teraz zastanawiam się, czy błędem jest używanie zarządzania sesją Hibernate ThreadLocal w tym scenariuszu. O ile rozumiem, ForkJoinPool używa mniejszej liczby wątków i dzieli je między działające zadania, podczas gdy inne zadania śpią. (Zmotywowane przez przeciągnięcie/denerwujące połączenia "zadania w transakcji") Chcę zamknąć() każdą sesję hibernacji po jednostce pracy

Tak więc, kiedy wywołuję HibernateSessionFactory.getThreadLocalSession(). Close() na koniec moim zadaniem - a zadanie jest uruchamiane w ForkJoinPool - pojawią się kłopoty mam upuść ThreadLocal wzorzec dla ciężkich równoległych obliczeń i zarządzania sesjami sobie

Dzięki z góry za wszelkie odpowiedzi

+0

Czy używasz SessionFactory.getCurrentSession() lub .openSession() do uzyskiwania obiektów Session? Jeśli getCurrentSession, jakiego używasz CurrentSessionContext? Zgaduję ThreadLocalSessionContext, ale określasz to jako "wzór" w przeciwieństwie do klasy. – sharakan

+0

Dzięki za zaglądanie do tego .. Uaktualniłem pytanie bardziej szczegółowo. – alfonx

Odpowiedz

4

Korzystanie?. ThreadLocalSessionContext może być problematyczne dla ciebie, ale zależy to od tego, co robisz.

A ForkJoinPool (javadocs) jest przeznaczony do użycia w przypadkach, gdy zadania odradzają inne zadania (widelec) i oczekiwania na ich zakończenie (dołączenie). Podczas oczekiwania wątek, który wykonywał zadanie nadrzędne, może być ponownie użyty do wykonania zadania potomnego. Według javadocs dla ThreadLocalSessionContext, Session zamyka się, gdy zatwierdzasz transakcję, którą otrzymujesz od niego (tj. Jest tylko jedna transakcja na Session).

Tak więc, jeśli masz zadanie "rodzica", które wywołuje sessionFactory.getCurrentSession() i wykonuje pewne czynności, a następnie wywołuje metodę commit(), sesja zostaje zamknięta i nie ma niebezpieczeństwa niewłaściwej interakcji.

Jednakże, jeśli tarło dzieci zadania Po wywołaniu .getCurrentSession() i przed wywołaniem .commit() można uruchomić w kwestii, ponieważ inne zadania mogą wykonywać na ten temat, a .getCurrentSession() wróci sesji używany przez zadanie macierzystej. To prawie na pewno nie jest to, czego chcesz, ponieważ zadania dla dzieci powinny prawdopodobnie robić to samo, co inne, a nie chciałbyś, aby jedno z nich dzieliło arbitralnie stan Session z rodzicem, podczas gdy inne nie.

Tak w skrócie, należy:

  • Nie zadzwonić session.close() jeśli masz Session z .getCurrentSession(), bo to w gestii CurrentSessionContext sobie z tym poradzić.
  • Bądź zaangażowany w związek przed urodzeniem dzieci. Mam na myśli, zadzwoń pod numer .commit() przed odrodzeniem zadań dla dzieci.

Jako przypis, znalazłem this wiki page jako pomocną lekturę na ten temat.