在这种情况下应该使用 try-finally

Anm*_*pta 1 java stack exception try-catch

在 DAO 层类中,假设我有如下代码:

private EntityManagerFactory factory;

public void update(T entity) {
    EntityManager entityManager = factory.createEntityManager();
    entityManager.getTransaction().begin();
    entityManager.merge(entity);
    entityManager.getTransaction().commit();
    entityManager.close();
}
Run Code Online (Sandbox Code Playgroud)

现在在上面的代码块中,在调用 entityManager.close() 之前,可能会(很少)发生 RuntimeExceptions。那么,这样写会不会很好:

public void update(T entity) {
    EntityManager entityManager = factory.createEntityManager();
    try {
        entityManager.getTransaction().begin();
        entityManager.merge(entity);
        entityManager.getTransaction().commit();
    }
     finally {
        entityManager.close();
    }
}
Run Code Online (Sandbox Code Playgroud)

由于我的方法中的所有对象都是本地的,一旦方法结束它们将不存在。那么,当方法内部发生异常时,该方法的堆栈会发生什么变化呢?

我认为如果堆栈存在异常情况,那么我确实需要 finally 块来关闭 entityManager。实际发生了什么?

Tho*_*mas 6

由于我的方法中的所有对象都是本地的,一旦方法结束它们将不存在。

不,对对象的引用是本地的,并在方法范围完成时删除,对象本身驻留在堆上,最终可能会被垃圾收集。为了安全起见,我会在 finally 语句中添加对 close() 的调用。

看看EntityManager.close()Hibernate 4.2.15的实现(我们还不能/不使用 Hibernate 4.3+,但我猜它看起来很相似),关闭传递给会话、事务协调器和 - 如果启用- 统计收集器。所有这些类都会自己做一些清理工作,比如清除一级缓存、关闭数据库连接、收集会话统计信息等。