Держать JPA EntityManager открытым? - PullRequest
14 голосов
/ 03 августа 2010

Я изучаю JPA, и общая схема в примерах выглядит следующим образом:

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

Теперь мне интересно, почему мы постоянно создаем и закрываем EntityManager, в отличие от сохранения его открытым и только запускановые транзакции?Каковы преимущества и затраты, связанные с тем, чтобы он оставался открытым по сравнению с его постоянным закрытием?

Ответы [ 2 ]

7 голосов
/ 03 августа 2010

На ум приходят две специфические для JPA причины:

  1. В соответствии со спецификацией JPA EntityManager не гарантирует многопоточность. Следовательно, портативные приложения JPA могут использовать EM только в одном потоке одновременно. Фракция создания EM локального метода и его закрытия до того, как он выйдет из области видимости, поощряет ограничение стека ссылками EM.

  2. EM, использующий «расширенный» контекст постоянства Lifetime поддерживает единый контекст постоянства на протяжении всего своего существования. Это означает, что сущности перестают автоматически отключаться на commit(). Вместо этого они должны быть отсоединены вручную, иначе EM остается ответственным за их отслеживание.

Этот вопрос действительно является специфической для JPA версией старого вопроса "когда собирать объекты". Это сложный вопрос, но ответ, вероятно, "редко".

Это старое сообщение developerWorks , написанное экспертом по параллелизму Java Брайаном Гетцем, объясняет эту мысль Суть: пулы имеют смысл для дорогостоящих объектов, таких как соединения с базой данных. Но для кратковременных, небольших и быстро инициализируемых объектов, таких как EntityManager, объединение в пул или некоторая другая форма долговременного сохранения ссылок является трудной задачей.

Но это общий вопрос, поэтому обязательно должны быть исключения. Возможно приложение простое или однопоточное. Тогда эти опасения по поводу безопасности потоков становятся спорными.

5 голосов
/ 03 августа 2010

Если менеджер сущностей открыт, он не может вернуть соединение с пулом соединений.

Это может привести к нескольким проблемам, особенно в веб-приложениях, например когда пул заполнен и максимальный размер соединения достигнут, никакой другой пользователь не может получить соединение с базой данных, предотвращая доступ к базе данных для этого пользователя.

В этом случае лучше иметь недолговечных менеджеров, например, открыть диспетчер сущностей в начале запроса и закрыть его в конце запроса (это можно сделать с помощью прослушивателей / перехватчиков ..). Затем сущности отсоединяются, и вам необходимо повторно присоединить их, если вы хотите использовать их снова (используя операцию слияния менеджера сущностей).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...