Создает ли диспетчер сущностей соединение с базой данных?

в моем проекте я забыл закрыть entity manager для каждой операции. Через некоторое время я получил исключение из-за чрезмерных подключений к серверу mysql. Означает ли это, что каждый диспетчер сущностей устанавливает соединение? Что произойдет, если мы забудем закрыть соединение? Я использовал только одну фабрику entity manager.

2 ответов


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

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

Если вы не закрываете менеджеров сущностей и продолжаете создавать их новые экземпляры, то вы можете исчерпать соединения в источнике данных JTA (для менеджеров сущностей JTA) или нажмите определенное сервером ограничение на клиентские подключения (как для JTA, так и для менеджеров локальных сущностей ресурсов). Каждый экземпляр базы данных будет настроен на прием не более определенного количества подключений. Если количество подключений, установленных всеми клиентами, превышает это ограничение, сервер просто отбросит дополнительные подключения. При открытии экземпляров entity manager, которые запрашивают дополнительные подключения из пула (для менеджеров сущностей JTA) или создают новые пулы (для локальной сущности ресурса менеджеры), то очень вероятно, что сам пул может быть исчерпан, или было бы открыто слишком много соединений.

поскольку вы не можете закрыть соединения напрямую или даже изменить размер пулов соединений из вашего приложения, совершенно очевидно, что вы должны закрыть экземпляры entity manager, когда они вам больше не нужны; это автоматически освободит соединения, которые были установлены для entity manager.

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


в любом случае-если вы явно открываете EntityManager (получите его от EMFactory), то вы должны закрыть его. Требуется ли подключение (что, по-видимому, ваш случай) или нет, зависит от настроек, связанных с поставщиком JPA. В нашем проекте EM открывает соединение для каждого запроса и немедленно возвращает его обратно (закрывает). Но есть и другие варианты-сохранить соединение или соединение, которое следует за жизненным циклом транзакции.

здесь настройки для Объектом openjpa. Я бы сказал, что если бы EM открыл соединение для запроса/транзакции, то вы не попали бы в проблему. Кажется, что ваш EM берет соединение и удерживает его.

в любом случае, вы должны закрыть EM, если вы его создали. Лучше всего сделать это тем же методом, если это возможно, поэтому легко проверить правильность и сделать это в finally block.