2013-06-26 3 views
2

EJB 애플리케이션을 구현 중입니다. 이 시점에서 나는 거래가 필요합니다. 나는 3 개의 메소드를 연속적으로 실행해야하며 하나가 실패하면 모든 것이 롤백되어야한다. 여기 : http://www.conceptgo.com/gsejb/eb04.html, 튜토리얼을 발견했습니다. 내 코드 :javax.transaction.UserTransaction을 사용하여 EJB에서 트랜잭션 구현하기

try { 
     javax.transaction.UserTransaction ut = (UserTransaction) ctx.lookup("java:comp/UserTransaction"); 
     ut.begin(); 
     Feeds feed = loadFeed(url); 

     try{ 
      em.persist(feed); 
      uf.setFeedId(feed.getFeedId()); 
      uf.setUserId(user_id);   
      em.persist(uf); 
     }catch (EntityExistsException e){ 
      ut.rollback(); 
      return false; 
     }catch (IllegalArgumentException ea){ 
      ut.rollback(); 
      return false; 
     } 
     if (feed.getFeedId()!= null && feed!=null) { 
      ut.commit(); 
     }else{ 
      ut.rollback(); 
      return false; 
     } 

내가 다음 오류 메시지가 얻을 내 응용 프로그램을 실행합니다

Caused by: java.lang.IllegalStateException: BaseTransaction.checkTransactionState 
- ARJUNA016051: thread is already associated with a transaction 

누구든지 어떤 원인이고 그 해결 방법을 알고 있습니까?

답변

5

이 오류는 이미 처리중인 트랜잭션 (컨테이너 관리 트랜잭션보다 많음)이 있음을 의미합니다.

빈/메소드의 모양은 무엇입니까? JBoss7의 무 상태 세션 빈에 대한 기본 트랜잭션 동작은 Container managed transaction과 'Required'트랜잭션 속성으로 실행된다는 것입니다.

그래서 컨테이너 관리 트랜잭션이 작동한다고 가정하면 UserTransaction이 필요하지 않습니다. 그래서 조회와 시작/커밋/롤백을 제거 할 수 있습니다.

트랜잭션을 직접 관리하려면 Bean 관리 트랜잭션을 사용하여 Bean을 표시 한 다음 UserTransaction을 시작/확약/롤백 할 수 있습니다. bean 관리 트랜잭션을 사용하여 bean을 표시하려면 @TransactionManagement (TransactionManagementType.BEAN) 주석을 클래스 또는 메소드에 적용해야합니다.

+0

안녕하세요. 답장을 보내 주셔서 감사합니다. 그것은 위대하게 들린다. 그러나, 내가하는 명령이 서로 관련이없는 것처럼 느껴집니다. 그리고 왜 ejb가 관련이없는 거래를 수행하는지 알 수 없습니까? 첫째로 피드 클래스 객체를 유지 한 다음 UserFeed 유형 객체를 유지합니다. em.persist (피드); uf.setFeedId (feed.getFeedId()); uf.setUserId (user_id); em.persist (uf); – Sermilion

+0

자, 직접 트랜잭션을 관리해야하는 경우, Bean이 트랜잭션 자체를 관리하고 UserTransactions를 사용할 것임을 선언해야합니다. 위의 내 대답을 업데이트했습니다. – Raylite3

2

오류로 JBoss에서 컨테이너 관리 트랜잭션을 중단하려고합니다. 자신 만의 방식으로 트랜잭션을 처리하려면 클래스/메소드 bean을 다음과 같이 변경하십시오.

@TransactionManagement(TransactionManagementType.BEAN) 
public void getTransaction(){ 
    //.... 
} 

이제 JBoss 끝에서 안전하지만 Bean 관리 트랜잭션에서 트랜잭션의 각 단계를 정의해야합니다.

+0

고맙습니다. 이 경우, 관리되는 컨테이너와 userTransactions의 일부 메소드를 관리하는 방법이 있습니다. 또는 bean의 모든 메소드가 userTransaction을 관리한다는 의미입니까? – Sermilion

+2

'@ TransactionManagement'는'@Target (ElementType.TYPE)'을 가지고 있으므로 클래스/인터페이스/....만으로 메소드에 주석을 추가 할 수 없습니다. – rzymek

1

CMT 컨테이너가 트랜잭션 및 관련 스레드를 처리하는 경우에 대비하여 CMT에는 몇 단계를 사용하고 BMT에는 몇 단계를 사용하지 않는 것이 좋습니다. 따라서 ejb 컨테이너는 트랜잭션에 참여한 객체에 대한 잠금을 획득하고 트랜잭션이 완료 될 때까지 릴리스되지 않습니다. 이러한 객체는 BMT에서 필요할 경우 문제를 일으킬 수 있습니다. 따라서 CMT 또는 BMT를 사용해야합니다.

+0

감사합니다. 그러나 때로는 persistent()와 같은 간단한 메소드를 사용할 때 BMT를 사용하는 경우 트랜잭션이 필요하므로 오류가 발생합니다. 그런 경우 어떻게해야합니까? – Sermilion

+1

귀하의 방법()에서 거래를 사용하고 있지만 귀하의 작업이 거래가 아니란 것을 의미합니다. 단순히 @TransactionAttribute (TransactionAttributeType.Required)를 사용하십시오. public void createDepartment() {} –

관련 문제