当前位置: 首页 > 面试题库 >

EntityManager真的是线程安全的吗?

慕翰学
2023-03-14
问题内容

我在这里谈论基本用法:

@Stateless
public class BookServiceBean implements BookService {
  @PersistenceContext EntityManager em;
  public void create(Book book) { this.em.persist(book);}
}

谷歌搜索以上问题,说是,但不是
-接受的答案是,是,但后续行动是否;Spring.io表示是和否,并且似乎是Java EE专家的Adam Bien给出了不合格的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(),即使我在两次调用之间仍在同一线程上,也会得到:

严重:java.lang.IllegalStateException:试图在关闭的EntityManager上执行操作

我知道我可以自己编写代码@PersistenceUnit private EntityManagerFactory emf;并管理EntityManager自己,但是我想利用@PersistenceContext提供给我的所有自动事务功能。


问题答案:

不,EntityManager不是线程安全的。亚当·比恩虽然也是正确的。您只是没有正确地看问题。他要回答的问题不是EntityManager是否是线程安全的,而是要说明在无状态会话Bean中使用容器管理的EntityManger是安全的。然后,他解释了允许容器发挥其魔力的规范的理由和措辞-“每个实例仅看到序列化的方法调用序列”。这允许容器注入在每个方法调用中具有不同的EntityManager上下文,类似于如何将每个调用绑定到其自己的事务和隔离的资源。

注入实际上只是注入EntityManager代理,该代理使容器可以控制下面的JPA EntityManagers的生命周期,从而使其可以与线程和事务绑定。

因此,EntityManager不是线程安全的,但是要求容器注入的EntityManager代理在无状态会话Bean中安全使用。



 类似资料:
  • 问题内容: 我已经在我的应用程序中以相同的方式使用了本教程:http : //www.benmccann.com/hibernate-with-jpa-annotations- and-guice/ 我的应用程序是JAX-RS Web服务,它将接收许多并发请求并进行数据库更新。 GenericDAOImpl.java实现: } 如果2个并发线程尝试保存实体,我得到 如果我评论交易,保存效果很好。

  • 问题内容: 在中,此变量被声明为是我的问题,在某些调用之后检查值还是在多线程代码中使用perror()是安全的。这是线程安全变量吗?如果没有,那还有什么选择呢? 我在x86体系结构上将Linux与gcc一起使用。 问题答案: 是的,它是线程安全的。在Linux上,全局errno变量是特定于线程的。POSIX要求errno必须是线程安全的。 参见http://www.unix.org/whitepa

  • 问题内容: 我们在项目中使用了Drools kieSessions。许多线程可以创建新的kieSession。有时在创建会话时线程可能会挂起。因此,问题是: 首先 是kieContainer.newKieSession线程安全操作吗? 上吊的原因可能是肮脏的文字或阅读的kie会话集之类的东西吗? 问题答案: 当我在实践中检查 不是线程安全的操作。

  • 问题内容: 在Java中:线程安全吗,即返回的迭代器是在任何时候反映列表的当前状态,还是仅在创建列表时反映列表的状态? 问题答案: List.iterator()的行为未定义或与其他List实现保持一致。 对于ArrayList,LinkedList,如果在迭代列表时对其进行了修改,则可以获得ConcurrentModificationException。(这不能保证)避免此问题的方法是使用syn

  • 此">答案提供了对IntStream进行分区的实现: 但是它的编辑提到这个实现不是线程安全的。然而,据我所知,收集器创建了一个单独的

  • 在我的应用程序中,我使用多个线程来处理客户端连接。 我在调试时发现了一个非常奇怪的行为——我有一个SelectionKey,通过调用(使用调试器)它的interestTops()方法,返回值是1(READ),但当我将数据发送到与该键对应的套接字时,选择器不会被唤醒。。 如果使用调试器,我将特定选择键更改为1(即使是1),选择器会突然对该更改做出反应。 在给定的时间内,我只有一个线程处理一个连接,但