多个线程在JUNIT中启动事务

时间:2011-12-15 21:23:50

标签: multithreading transactions junit entitymanager

我试图通过编写单元测试来重现(而不是全面测试多线程问题)我的一种方法中的线程阻塞问题。因为我看到了很多

的例子
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可以在任何给定时间出现多个活动线程(因此是一个单独的实体管理器)?

我在这里错过了什么吗?

由于

1 个答案:

答案 0 :(得分:0)

EntityManager不是线程安全的。这就是为什么经常告诉你不应该将EntityManager注入Servlet这样的共享实例。它清楚地记录在案(JSR-317第286页):

  

不能同时在多个实体管理器之间共享实体管理器   执行线程,作为实体管理器和持久化上下文   不要求线程安全。只能访问实体经理   以单线程方式。