我正在学习JPA,示例中的一般模式如下:

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

现在我想知道为什么我们要不断创建和关闭EntityManager,而不是保持打开状态并仅开始新事务?始终保持打开状态与关闭状态有什么好处和成本?

最佳答案

我想到了两个针对JPA的原因:

JPA规范不保证

  • EntityManager是线程安全的。因此,便携式JPA应用程序一次最多只能在一个线程中使用EM。创建方法本地EM并在超出范围之前将其关闭的习惯用法鼓励对EM引用进行堆栈限制。
  • 使用“扩展的”持久性上下文生命周期的EM为其整个存在维护一个持久性上下文。这意味着实体停止在commit()上自动分离。相反,必须手动分离它们,否则EM仍然负责跟踪它们。

  • 这个问题实际上是旧的“何时池对象”问题的JPA特定版本。这是一个艰难的过程,但答案可能是“很少”。

    Java并发专家Brian Goetz的old developerWorks post阐述了这一点。要点:池对于昂贵的对象(如数据库连接)非常有意义。但是对于诸如EntityManager之类的短暂,小型且快速初始化的对象而言,池化或其他形式的长期引用保留很难。

    但是,这是一个普遍的问题,因此必然会有异常(exception)。也许应用程序是简单的还是单线程的。然后,关于线程安全性的这些关注就变得毫无意义。

    07-24 09:38
    查看更多