2014-04-17 3 views
0

고객이 System의 테스트 성능 테스트를 작성하길 원합니다. 하지만 엔티티 관리자에 문제가 있습니다. 내가 사업에 하나 개의 방법이 : 여기멀티 스레드 및 엔티티 관리자가있는 Junit 테스트가 작동하지 않습니다.

@Transactional(isolation = Isolation.READ_COMMITTED) 
public ProductSequence generate(String prefix) { 
    if (StringUtils.isBlank(prefix)) { 
     throw new IllegalArgumentException("prefix is blank"); 
    } 
    ProductSequence productSequence = new ProductSequence(); 
    List<ProductSequence> lstProductSequences = getProductSequenceByPrefix(prefix); 

    if (!lstProductSequences.isEmpty()) { 
     productSequence = lstProductSequences.get(0); 
     productSequence.setSequence(productSequence.getSequence() + 1); 
     this.entityManager.merge(productSequence); 

    } else { 
     productSequence.setPrefix(prefix); 
     productSequence.setSequence(1L); 
     this.entityManager.persist(productSequence); 
//want to check again if data was persisted or not 
     List<ProductSequence> lstProductSequences2 = getProductSequenceByPrefix(prefix); 
     if (lstProductSequences2.isEmpty()) { 
      System.out.println("cannt persist entity manager"); 
     } 

    } 
    return productSequence; 

} 

/** 
* get product list by prefix. 
* 
* @param prefix 
*   <code>String</code> 
* @return List<ProductSequence> 
*/ 
@Transactional 
public List<ProductSequence> getProductSequenceByPrefix(String prefix) { 
    TypedQuery<ProductSequence> typedQuery = entityManager.createQuery(
      "SELECT o FROM ProductSequence AS o WHERE o.prefix = :prefix", ProductSequence.class); 

    typedQuery.setParameter("prefix", prefix); 
    return typedQuery.getResultList(); 
} 

그리고 것은 테스트 실행이 testGenerateWithoutThread 방법은 잘 작동하지만 testGenerateWithThread가 메모리에 데이터를 유지 cannt 때 문제는 이러한 방법

final String prefix = "TEST-AUTO"; 
final List<String> tags = new LinkedList<String>(); 
@Test 
public void testGenerateWithThread() { 



    final int loops = 5; 

    final int threadCount = 1; 

    final CyclicBarrier barrier = new CyclicBarrier(threadCount + 1); 

    final boolean[] error = new boolean[] { false }; 

    Thread[] threads = new Thread[threadCount]; 
    for (int i = 0; i < threads.length; i++) { 
     final int t = i; 
     Runnable r = new Runnable() { 
      @Override 
      @Transactional 
      public void run() { 
       try { 
        barrier.await(); 
       } catch (InterruptedException e) { 
        error[0] = true; 
       } catch (BrokenBarrierException e) { 
        error[0] = true; 
       } 
       for (int j = 0; j < loops; j++) { 
        String tagGenerate = productSequence.generate(prefix); 
        tags.add(tagGenerate); 
        System.out.println("In thread " + t + ": " + tagGenerate); 
       } 
      } 
     }; 
     threads[i] = new Thread(r); 
     threads[i].start(); 
    } 

    try { 
     barrier.await(); 
    } catch (InterruptedException e1) { 
     System.out.println("Interrupted whilst waiting for barrier"); 
    } catch (BrokenBarrierException e1) { 
     System.out.println("Broken barrier"); 
    } 

    for (int i = 0; i < threads.length; i++) { 
     try { 
      threads[i].join(); 
     } catch (InterruptedException e) { 
      System.out.println("Interrupted whilst joining thread " + i); 
     } 
    } 

    assertEquals(threadCount * loops, tags.size()); 
} 

/** 
* test for generate function 
*/ 
@Test 
@Transactional 
public void testGenerateWithoutThread() { 
    for (int i = 1; i <= 5; i++) { 
     String tagGenerate = productSequence.generate(prefix); 
     System.out.println("tag gen " + tagGenerate); 
     assertEquals(prefix + "-" + i, tagGenerate); 
    } 
} 

에 대한 시험 방법 데이터 베이스. testGenerateWitThread가 "TEST-AUTO-1"이지만 testGenerateWithoutThread가 "TEST-AUTO-1", "TEST-AUTO-2", "TEST-AUTO-3", "TEST-AUTO"일 때 태그 목록의 모든 값이 나열됩니다. -4 ","TEST-AUTO-5 ". 이유를 모르겠습니다. 멀티 스레드 테스트를 실행하면 엔티티 관리자가 메모리 데이터베이스에 데이터를 저장할 수 없지만 정상적인 방법은 있습니까?

저를 도와주세요! 고마워!

+0

가 무엇 그것이 다섯 번째 통과에 두 번째에거야? 예외가 발생하여 종료됩니까? 지속 후에도 쿼리 이전에 this.entityManager.flush()를 사용하면 어떻게됩니까? – Chris

답변

0

testGenerateWithThread()은 에 있었기 때문에 @Transactional 태그가 필요합니다. 다음을 시도해보십시오 : 나사 버전은 단지 루프에서 로깅을 수행하기 때문에

@Test @Transactional public void TestGenerateWithThread() { 

    final int loops = 5; 

    final int threadCount = 1; 

    final CyclicBarrier barrier = new CyclicBarrier(threadCount + 1); 

    final boolean[] error = new boolean[] { false }; 

    Thread[] threads = new Thread[threadCount]; 
    for (int i = 0; i < threads.length; i++) { 
     final int t = i; 
     Runnable r = new Runnable() { 
      @Override 
      @Transactional 
      public void run() { 
       try { 
        barrier.await(); 
       } catch (InterruptedException e) { 
        error[0] = true; 
       } catch (BrokenBarrierException e) { 
        error[0] = true; 
       } 
       for (int j = 0; j < loops; j++) { 
        String tagGenerate = productSequence.generate(prefix); 
        tags.add(tagGenerate); 
        System.out.println("In thread " + t + ": " + tagGenerate); 
       } 
      } 
     }; 
     threads[i] = new Thread(r); 
     threads[i].start(); 
    } 

    try { 
     barrier.await(); 
    } catch (InterruptedException e1) { 
     System.out.println("Interrupted whilst waiting for barrier"); 
    } catch (BrokenBarrierException e1) { 
     System.out.println("Broken barrier"); 
    } 

    for (int i = 0; i < threads.length; i++) { 
     try { 
      threads[i].join(); 
     } catch (InterruptedException e) { 
      System.out.println("Interrupted whilst joining thread " + i); 
     } 
    } 

    assertEquals(threadCount * loops, tags.size()); 
} 
+0

답장을 보내 주셔서 감사합니다. 하지만 난 testGenerateWithThread()에 넣어하려고하지만 작동하지 않습니다. – binhnguyen

관련 문제