2015-01-14 2 views
0

다음 코드를 사용하여 사용자를 저장하고 JMS 메시지를 보냅니다. 현재 saveUserSendMessage을 UserTransaction으로 감싸고 있습니다. 트랜잭션이 중첩 될 때 ejb에서 예외가 발생합니다. 중첩 된 트랜잭션을 가능하게하려면 아래에서 무엇을해야합니까?ejb sessionbean - bean 관리 트랜잭션의 중첩 된 트랜잭션

@Resource(mappedName = "java:/JmsXA") 
private static QueueConnectionFactory queueConnectionFactory; 

@Resource(mappedName = "EjbQueueJndi") 
private static Queue queueProp; 

@PersistenceContext(unitName = "ejbPersistanceunit") 
private EntityManager em; 

@Resource 
UserTransaction ut; 

@Override 
public boolean saveUserSendMessage(String name, String email, int age, 
     boolean arg3) throws Exception { 

    UserTransaction xact = ut; 
    xact.begin(); 

    saveUser(name, email, age); 
    sendMessage("Successfully saved the user"); 
    try { 
     if (arg3) 
      throw new Exception("Unsuccessfull"); 
     xact.commit(); 
    } catch (Exception e) { 
     xact.rollback(); 
     throw e; 
    } 
    return true; 
} 

@Override 
public boolean saveUser(String name, String email, int age) 
     throws Exception { 
    try { 
     ut.begin(); 
     UserEntity ue = new UserEntity(); 
     ue.setAge(age); 
     ue.setEmail(email); 
     ue.setName(name); 
     em.persist(ue); 
     ut.commit(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
     throw e; 
    } 
    return true; 
} 

예외 내가 얻을 :

15:51:04,127 ERROR [STDERR] javax.transaction.NotSupportedException: BaseTransaction.checkTransactionState - [com.arjuna 
.ats.internal.jta.transaction.arjunacore.alreadyassociated] [com.arjuna.ats.internal.jta.transaction.arjunacore.alreadya 
ssociated] thread is already associated with a transaction! 
+0

빈 관리 트랜잭션을 사용하여 그렇게 할 수 있다고 생각하지 않습니다. 컨테이너 관리 트랜잭션 내에서 가능하지만 동일한 메소드 내에서 가능하지 않습니다. – EdH

+0

같은 수업을 의미합니까?/ – Zeus

+1

나는 방법을 의미했습니다. CMT를 사용하고 RequiresNew가있는 메소드는 중첩 된 트랜잭션을 지원해야하지만 CMT를 사용하더라도 해당 메소드 내에서 수행 된 모든 코드는 단일 트랜잭션이됩니다. 같은 객체가 서비스 레이어를 통해 호출되는 경우, 다른 메소드를 자신의 RequiresNew 정의로 호출하면 새 트랜잭션을 사용할 수 있다고 생각됩니다. 그러나이 모든 것은 CMT이며,이 중 어떤 것도 BMT에 가능하다고 언급하지 않습니다. – EdH

답변

2

자바 EE는 중첩 된 트랜잭션을 지원하지 않습니다. 트랜잭션을 일시 중단하고 관련없는 트랜잭션을 실행하며 첫 번째 트랜잭션을 다시 시작하는 것이 유일한 지원입니다.

이렇게하려면 RequiresNew 트랜잭션 특성을 사용하는 다른 EJB를 호출해야합니다. 메시지 수신 확인이 롤백 되더라도 내부 트랜잭션이 완료 될 수 있습니다. 이는 메시징 엔진이 충돌 할 경우 두 번째 트랜잭션이 다시 실행될 수 있음을 의미합니다. 또는 빈 관리 트랜잭션을 사용하도록 EJB를 변경할 수도 있습니다. 이는 유사한 효과를 가져옵니다.

정말로 하시겠습니까? 컨테이너 관리 트랜잭션 내에서 논리를 실행하는 것이 가장 좋습니다.