Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 让JPA EntityManager保持打开状态?_Java_Orm_Jpa - Fatal编程技术网

Java 让JPA EntityManager保持打开状态?

Java 让JPA EntityManager保持打开状态?,java,orm,jpa,Java,Orm,Jpa,我正在学习JPA,示例中的一般模式如下: EntityManager em = factory.createEntityManager(); em.getTransaction().begin(); // .... em.getTransaction().commit(); em.close(); 现在我想知道为什么我们要不断地创建和关闭EntityManager,而不是保持它的开放性并开始新的事务?始终保持开放与关闭的好处和成本是什么?想到JPA的两个具体原因: 根据JPA规范,Entity

我正在学习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对此进行了阐述。要点:池对于昂贵的对象(如数据库连接)非常有意义。但是对于像EntityManager这样的短期、小型和快速初始化对象,池或其他形式的长期引用保留是一个很难解决的问题


    但是,这是一个普遍的问题,所以肯定会有例外。也许应用程序是简单的或单线程的。然后,这些关于线程安全的担忧就变得毫无意义了。

    保持实体管理器打开会阻止它将连接返回到连接池

    这可能会导致一些问题,尤其是在web应用程序中,例如,当池已满且达到最大连接大小时,其他用户无法获得阻止该用户访问数据库的数据库连接

    在这种情况下,最好使用寿命较短的实体管理器,例如,在请求开始时打开实体管理器,在请求结束时关闭实体管理器(可以使用侦听器/拦截器..)。然后,实体将分离,如果要再次使用它们,则必须重新附着它们(使用实体管理器的合并操作)