我们的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块中关闭它。我们正在测试Jersey应用程序,因此我们的JUnit测试扩展了JerseyTest。每个测试方法都实例化一个Grizzly容器,运行测试,然后关闭容器。 EntityManagerFactory由spring注入。我们使用JPA而不是Hibernate。
我正在监控与MySQL测试数据库的连接,它们总是很高。一个测试单独运行MySQL“Max_used_connections”变量为38.为了好玩,我去了所有em.close()调用注释,测试仍然使用38个连接。
我正在使用Hibernate的内置连接池(我知道不是用于prod使用)。我仍然期待某种智能汇集。
我处理EntityManager错了吗?我怎么能关闭连接?
答案 0 :(得分:5)
您应该在测试结束时close
EntityManagerFactory
。来自EntityManagerFactory#close()
的javadoc:
void javax.persistence.EntityManagerFactory.close()
关闭工厂,释放它所拥有的任何资源。关闭工厂实例后,在其上调用的所有方法都将抛出
IllegalStateException
,isOpen
除外,它将返回false。一旦EntityManagerFactory
关闭,其所有实体经理都被视为处于关闭状态。
作为旁注,您应该在关闭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();
}
}
}
答案 1 :(得分:2)
为什么你认为EntityManager.close()
总是在物理上关闭底层连接?这取决于连接池(您可能需要配置它并设置同时打开的连接的最大数量)。