【问题标题】:EntityManager thread safety and Java EEEntityManager 线程安全和 Java EE
【发布时间】:2015-05-16 20:34:44
【问题描述】:

我是 EJB 和休眠的新手,以下内容让我感到困惑,因为每当我寻找明确的答案时似乎都会出现矛盾。 问题:

通过以下方式将Entity manager直接注入到无状态bean中是否线程安全?

@Stateless
public class SomeBean implements SomeInterface {

//..    
@Inject
private EntityManager entityManager;

//... non related transaction1()
//... non related transaction2()

每个无状态 bean 是否有自己的 EntityManager 实例或可以注入共享实例?

根据 Hibernate 文档:

EntityManager 是一个廉价的、非线程安全的对象,应该为单个业务流程、单个工作单元使用一次,然后丢弃。

EJB 容器是否使其成为线程安全的?

根据 EJB 文档,无状态会话 bean 本质上是线程安全的,不允许不同的客户端同时操作同一个 bean。

但是,我已经阅读了应该注入 EntityManagerFactory 而不是 EntityManager 的示例,如果直接注入 EntityManager,则应该在 Stateful bean 中完成。

始终将 EJB 直接注入到无状态 bean 中是否安全,如上所示,或者当它不起作用时会有什么用例?

【问题讨论】:

    标签: multithreading hibernate jakarta-ee ejb


    【解决方案1】:

    每个无状态 bean 是否有自己的 EntityManager 实例或可以注入共享实例?

    两者都不是。 @Inject(和@PersistenceContext@EJB)注入一个代理实例,而不是实际的实例。

    代理将在每个方法调用上委托当前线程和上下文中正确的可用实例。换句话说,容器担心这一切,而不是你。

    另见:

    【讨论】:

    • 那么,如果有 10 个线程调用同一个事务服务,每个线程都会有自己的实体管理器?
    • 如果有 10 个线程调用注入的 EntityManager 上的方法,那么是的。
    • @BalusC:在 servlet 中注入 EntityManager 怎么样?它仍然使用线程安全代理吗?
    • @BalusC:但是当具有实例变量 entityManager 的同一个无状态 bean 返回到池中时,前一个用户留下的状态将被下一个用户看到/可用。不会吧?那不可能是线程安全的。
    • @Shirgill:正如回答,@PersistenceContext 也注入了一个代理。
    猜你喜欢
    • 1970-01-01
    • 2012-03-23
    • 1970-01-01
    • 1970-01-01
    • 2010-10-12
    • 1970-01-01
    • 1970-01-01
    • 2011-09-03
    • 2012-06-19
    相关资源
    最近更新 更多