2010-08-03 12 views
14

uczę JPA i ogólny wzór w przykładach wydaje się być następująca:Prowadzenie otwartego menedżera JPA EntityManager?

EntityManager em = factory.createEntityManager(); 
em.getTransaction().begin(); 
// .... 
em.getTransaction().commit(); 
em.close(); 

Teraz zastanawiam się dlaczego ciągle tworzyć i bliskie EntityManagers, w przeciwieństwie do utrzymania go otworzyć i dopiero zaczynasz nowych transakcji? Jakie są korzyści i koszty związane z utrzymaniem otwartości a zamknięciem jej przez cały czas?

Odpowiedz

7

Dwa JPA-konkretne powody przychodzą na myśl:

  1. EntityManager nie jest gwarantowana być wątkowo przez spec WZP. Dlatego przenośne aplikacje JPA mogą używać EM tylko w jednym wątku na raz. Idiom tworzenia metody-lokalnego EM i zamykania go, zanim wykracza poza zakres, zachęca do przechowywania EM referencji.

  2. EM przy użyciu "rozszerzonego" kontekstu trwałości Dożywotnie utrzymuje pojedynczy kontekst utrwalania dla całego swojego istnienia. Oznacza to, że jednostki przestają automatycznie odłączać się od commit(). Zamiast tego należy je ręcznie odłączyć, inaczej EM pozostanie odpowiedzialny za ich śledzenie.

To pytanie jest naprawdę specyficzną dla WZP wersją starego pytania "kiedy grupować obiekty". To trudne, ale odpowiedź jest prawdopodobnie "rzadko".

Ten old developerWorks post przez eksperta Java współbieżności Brian Goetz wyjaśnia punkt. Istota: pule mają wielki sens w przypadku kosztownych obiektów, takich jak połączenia z bazą danych. Jednak w przypadku krótkotrwałych, małych i szybko inicjujących obiektów, takich jak EntityManager, łączenie lub inna forma długoterminowej retencji referencyjnej, trudno jest sprzedać.

Ale to ogólne pytanie, więc z pewnością będą wyjątki. Może aplikacja jest prosta lub singlethreaded. Następnie obawy dotyczące wątków bezpieczeństwa stają się dyskusyjne.

5

Pozostawienie otwartego menedżera encji uniemożliwi mu przywrócenie połączenia z pulą połączeń.

Może to prowadzić do wielu problemów, szczególnie w aplikacjach internetowych, np. kiedy pula jest pełna, a maksymalny rozmiar połączenia jest osiągnięty, żaden inny użytkownik nie może uzyskać połączenia z bazą danych, uniemożliwiając dostęp do bazy danych dla tego użytkownika.

W takim przypadku lepiej jest mieć menedżerów obiektów o krótkiej żywotności, np. Otwórz menedżera encji na początku żądania i zamknij go na końcu żądania (można to zrobić za pomocą detektorów/przechwytywaczy). Obiekty zostają odłączone i musisz je ponownie dołączyć, jeśli chcesz je ponownie użyć (używając operacji scalania menedżera jednostki).

Powiązane problemy