JAVA:多线程环境中的EntityManager对象

use*_*188 22 java persistence entitymanager

如果我有多个线程,每个使用注入器来获取EntityManager对象,每个使用em对象来选择其他类对象的列表.准备用于for循环.

如果一个线程首先完成并调用clear(),那会影响其他线程吗?喜欢for循环会有异常吗?

close()怎么样?

如果答案是"它取决于",那么(类定义?方法调用?)和where(java code?annotation?xml?)应该看看它是如何依赖的?

我没有写源,我只是在没有文档的情况下使用其他人的库.

谢谢.

Mak*_*kky 28

这是完整的工作thread-safe Entity Manager Helper.

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class EntityManagerHelper {

    private static final EntityManagerFactory emf;
    private static final ThreadLocal<EntityManager> threadLocal;

    static {
        emf = Persistence.createEntityManagerFactory("Persistent_Name");
        threadLocal = new ThreadLocal<EntityManager>();
    }

    public static EntityManager getEntityManager() {
        EntityManager em = threadLocal.get();

        if (em == null) {
            em = emf.createEntityManager();
            // set your flush mode here
            threadLocal.set(em);
        }
        return em;
    }

    public static void closeEntityManager() {
        EntityManager em = threadLocal.get();
        if (em != null) {
            em.close();
            threadLocal.set(null);
        }
    }

    public static void closeEntityManagerFactory() {
        emf.close();
    }

    public static void beginTransaction() {
        getEntityManager().getTransaction().begin();
    }

    public static void rollback() {
        getEntityManager().getTransaction().rollback();
    }

    public static void commit() {
        getEntityManager().getTransaction().commit();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 一个关于如何在多线程应用程序中使用此帮助器的简单示例将非常有用。:) (2认同)

pru*_*nge 12

实体管理器不是线程安全的(源Java EE 6教程),并且不能在线程之间共享.每个线程都需要使用自己的实体管理器,否则会发生不好的事情,无论是调用clear()还是close()调用.

但是,如果注入器使用自己的实体管理器注入每个线程,那么事情应该没问题.

Spring和可能的其他DI框架会将真实实体管理器的基于ThreadLocal的代理注入到bean中.每个线程所做的调用将代理实体管理器的真实线程本地实例 - 这就是事情可以工作的方式,即使它可能看起来实体管理器在多个线程之间共享.

有关如何注入实体管理器的更多细节将有所帮助(Spring等)

  • “每个线程都需要使用自己的实体管理器,否则会发生不好的事情。” 有什么问题可以请您详细说明。 (2认同)

ger*_*tan 4

管理 EntityManager 有两种类型:容器管理和应用程序管理。对于应用程序管理,获取EntityManager的首选方法是通过EntityManagerFactory。Java EE 教程是这样说的:

\n\n
\n

容器管理的实体管理器

\n\n

使用容器管理的实体管理器,EntityManager 实例\xe2\x80\x99s 持久性上下文会由容器自动传播到在单个 Java\n 事务 API (JTA) 中使用 EntityManager 实例的所有应用程序组件\n ) 交易。

\n\n

JTA 事务通常涉及跨应用程序组件的调用。\n 要完成 JTA 事务,这些组件通常需要访问\n单个持久性上下文。当通过 javax.persistence.PersistenceContext 注释将 EntityManager 注入到应用程序组件时,就会发生这种情况。持久性上下文会随当前 JTA 事务自动传播,并且映射到同一持久性单元的 EntityManager 引用提供对该事务内持久性上下文的访问。通过自动传播持久性上下文,应用程序组件不需要将 EntityManager 实例的引用相互传递,以便在单个事务中进行更改。Java EE 容器管理容器管理的实体管理器的生命周期。

\n\n

要获取 EntityManager 实例,请将实体管理器注入\n 应用程序组件:

\n\n
@PersistenceContext \nEntityManager em; \n
Run Code Online (Sandbox Code Playgroud)\n\n

应用程序管理的实体管理器

\n\n

另一方面,对于应用程序管理的实体管理器,持久性上下文不会传播到应用程序组件,并且 EntityManager 实例的生命周期由应用程序管理。

\n\n

当应用程序需要访问不使用 JTA 事务在特定持久性单元中跨 EntityManager 实例传播的持久性上下文时,将使用应用程序管理的实体管理器。在这种情况下,每个 EntityManager 都会创建一个新的、隔离的持久性上下文。EntityManager 及其关联的持久性上下文由应用程序显式创建和销毁。当无法直接注入 EntityManager 实例时,也会使用它们,因为 EntityManager 实例不是线程安全的。EntityManagerFactory 实例是线程安全的。

\n
\n\n

http://docs.oracle.com/javaee/6/tutorial/doc/bnbqw.html

\n