我在这里谈论基本用法:
@Stateless
public class BookServiceBean implements BookService {
@PersistenceContext EntityManager em;
public void create(Book book) { this.em.persist(book);}
}
谷歌搜索上面的问题,StackOverflow说yes, but no-可接受的答案是"is",但是后续的回答是“否”。 Spring.io说both yes and no,似乎是Java EE专家的Adam Bien给出了unqualified yes。
我自己对一个简单的调度bean的经验表明答案是否定的:
@Stateless
public class TimerTick implements TimerTickAbs, Runnable {
@PersistenceContext private EntityManager entityManager;
@Override
public void run() {
Query q = entityManager.createQuery("SELECT blah...");
}
@Override
public Runnable runner() {
return this;
}
}
抽象界面:
@Local
public interface TimerTickAbs {
public Runnable runner();
}
开始于:
@Resource ManagedScheduledExecutorService managedExecutorService;
@EJB TimerTick myRunner;
public void startup()
{
managedExecutorService.scheduleAtFixedRate(myRunner.runner(), 3, 40, TimeUnit.SECONDS);
}
如果我打印出
Thread.currentThread().getId()
,即使我在两次调用之间仍处在同一线程上,我也会得到:我知道我可以做类似
@PersistenceUnit private EntityManagerFactory emf;
的代码并自己管理EntityManager
,但是我想利用@PersistenceContext
给我的所有自动交易功能。 最佳答案
不,EntityManager不是线程安全的。亚当·比恩(Adam Bien)也是正确的。您只是没有正确地看问题。他要回答的问题不是EntityManager是否是线程安全的,而是要说明在无状态 session Bean中使用容器管理的EntityManger是安全的。然后,他解释了允许容器发挥其魔力的规范的理由和措辞-“每个实例仅看到序列化的方法调用序列”。这允许容器注入(inject)在每个方法调用中具有不同的EntityManager上下文,类似于每个调用可以如何绑定(bind)到其自己的事务和隔离的资源上。
注入(inject)实际上只是注入(inject)EntityManager代理,该代理使容器可以控制下面的JPA EntityManager的生命周期,从而使其能够与线程和事务绑定(bind)。
因此,EntityManager不是线程安全的,但是要求容器注入(inject)的EntityManager代理在无状态 session Bean中安全使用。
关于java - EntityManager真的是线程安全的吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24643863/