我们的 DAO 层中有 19 个方法,每个方法都是以下方法的一些变体:
public TicketProp saveTicketProp(TicketProp prop) {
EntityManager em = this.emf.createEntityManager();
try {
em.getTransaction().begin();
prop = (TicketProp) em.merge(prop);
em.getTransaction().commit();
return prop;
} finally {
em.close();
}
}
含义:在每个方法中我们处理自己的事务并在 finally block 中关闭它。我们正在测试 Jersey 应用程序,因此我们的 JUnit 测试扩展了 JerseyTest。每个测试方法实例化一个 Grizzly 容器,运行测试,然后关闭容器。 EntityManagerFactory 由 spring 注入(inject)。我们在 Hibernate 上使用 JPA。
我正在监控与我们的 MySQL 测试数据库的连接,它们总是很高。单独一项测试将 MySQL“Max_used_connections”变量运行到 38。为了好玩,我去了并注释掉所有 em.close() 调用,测试仍然使用 38 个连接。
我正在使用 Hibernate 的内置连接池(我知道不是用于生产环境)。我仍然期待某种智能池化。
我对 EntityManager 的处理有误吗?我还能如何关闭连接?
最佳答案
您应该关闭
EntityManagerFactory
在测试结束时。来自 EntityManagerFactory#close()
的 javadoc :
void javax.persistence.EntityManagerFactory.close()
Close the factory, releasing any resources that it holds. After a factory instance has been closed, all methods invoked on it will throw the
IllegalStateException
, except forisOpen
, which will return false. Once anEntityManagerFactory
has been closed, all its entity managers are considered to be in the closed state.
作为旁注,您实际上应该在 finally
子句中关闭 EM 之前回滚事务:
public TicketProp saveTicketProp(TicketProp prop) {
EntityManager em = this.emf.createEntityManager();
try {
em.getTransaction().begin();
prop = (TicketProp) em.merge(prop);
em.getTransaction().commit();
return prop;
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if (em.isOpen()) {
em.close();
}
}
}
关于mysql - 确保关闭 EntityManager 连接的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3348140/