2011-12-15 81 views
1

我想通過編寫一個單元測試來重現(而不是全面測試多線程問題)線程塊問題。因爲我看到很多實例的在JUNIT中啓動一個事務的多線程

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) 

這不是讓我用一個錯誤的第二個線程創建交易「交易已經有效」。我認爲EntityManager可以在任何給定時間出現多個活動線程(因此是單身實體管理員)?

我在這裏錯過了什麼嗎?

謝謝

回答

0

EntityManager不是線程安全的。這就是爲什麼經常被告知你不應該將EntityManager注入到像Servlets這樣的共享實例。它清楚地記錄(JSR-317頁286):

An entity manager must not be shared among multiple concurrently executing threads, as the entity manager and persistence context are not required to be threadsafe. Entity managers must only be accessed in a single-threaded manner.

+0

我試圖創建多個EntityManagers併爲每個線程關聯,但我還是會遇到「主題已經被激活」後第一個線程創建活動的Tx。 – phewataal 2011-12-20 18:54:41