我试图通过编写单元测试来重现(而不是全面测试多线程问题)我的一种方法中的线程阻塞问题。因为我看到了很多
的例子org.hibernate.exception.LockAcquisitionException: could not execute update query
在我们的2服务器PROD环境中,我应该能够在单元测试中相当容易地重现。 我试图在我的JUnit方法中生成多个线程,每个线程调用我的方法。我尝试用2个线程开始。
ExecutorService exec = Executors.newFixedThreadPool(16);
for (int i = 0; i < 2; i++) {
exec.execute(new Runnable() {
public void run() {
System.out.println("who is running: " + Thread.currentThread().getId());
em.getTransaction().begin();
//do something()
em.getTransaction().commit();
}
});
}
我收到错误:
Exception in thread "pool-1-thread-2" who is running: 11
java.lang.IllegalStateException: Transaction already active
at org.hibernate.ejb.TransactionImpl.begin(TransactionImpl.java:35)
不要让我为第二个线程创建一个错误'Transaction is already Active'的Transaction。我认为EntityManager可以在任何给定时间出现多个活动线程(因此是一个单独的实体管理器)?
我在这里错过了什么吗?
由于
答案 0 :(得分:0)
EntityManager不是线程安全的。这就是为什么经常告诉你不应该将EntityManager注入Servlet这样的共享实例。它清楚地记录在案(JSR-317第286页):
不能同时在多个实体管理器之间共享实体管理器 执行线程,作为实体管理器和持久化上下文 不要求线程安全。只能访问实体经理 以单线程方式。