2012-11-13 3 views
3

안녕하세요 여러분, 다음 문제에 대한 도움을 찾고 있습니다. 완벽하게 작동하는 jpa/stateless ejb의 proyect가 있습니다. 간단한 쿼리를 수행하고 작업을 지속하지만 지금은 필요합니다. 그 중 하나가 실패 할 경우 작업을 지속 집합을 실행하기 위해, 내가 롤백을 수행해야합니다, 그래서 내가 JTA는 일을하지만, 소스 코드의 조각을 사용 할 수 있습니다 발견 :EJB와 JPA에서 JTA 트랜잭션을 사용하십시오.

@Stateless 
public class ProjectBean implements IProject { 

@Resource 
javax.transaction.UserTransaction utx; 
@PersistenceContext(unitName = "JPADB") 
private EntityManager entityManager; 
    ... 
//more code 

//this is part of a method 
try{ 
utx.begin(); 
entityManager.joinTransaction(); 
    for(Project p:projectResultList){ 
       entityManager.persist(p); 
      } 
      utx.commit(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
      if(utx != null) 
       try { 
        utx.rollback(); 
       } catch (IllegalStateException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } catch (SecurityException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } catch (SystemException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
       //tx.rollback(); 
     } 

단순히 작동하지 않습니다, 그리고 이것은 persistence.xml의 모습입니다 :

<persistence-unit name="JPADB"> 
<jta-data-source>java:jboss/datasources/OracleBic</jta-data-source> 
    <properties> 
     <property name="hibernate.show_sql" value ="true" /> 
     <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" /> 
    </properties> 
</persistence-unit> 

정말 홉 누구나 나에게 팁이나 조언을 줄 수있다. jpa/jta 개념을 가진 초보자이고 웹에서 발견 된 많은 코드를 시도했지만 항상 다른 오류를 얻는다. (스레드에서 잘못된 tx : 예상 TransactionImple usertransaction이 시작될 수 없다. JTA를 사용하는 동안 EntityTransaction). 미리 감사드립니다.

+3

왜 bean 코드로 트랜잭션을 관리하고 있습니까? 응용 프로그램 서버를 신경 써서 그냥 두어도됩니다. 이'@Resource private SessionContext context '처럼 ejb에 컨텍스트를 삽입하고 예외 catch 블록 내에서'context.setRollbackOnly();를 호출해야합니다. – remigio

답변

2

@TransactionManagement (TransactionManagementType.BEAN)를 메소드 레벨에서 수동으로 처리하도록 AS에 지시 했습니까? 수업 수준에서 특수 효과가 표시되지 않습니다. 아마 당신은 메소드 레벨에서 그것을 가지고 있지만 코드를 잘라내는 것은 어떤 추측을하기에는 불충분하다. 그렇지 않으면 모든 트랜잭션이 컨테이너 관리이며 코드가 작동하지 않습니다. 따라서 어느 쪽이든 넣어야합니다. @TransactionManagement (TransactionManagementType.BEAN) 은 메소드 또는 클래스 수준에서 요구 사항에 따라 달라 지거나 컨테이너가 사용자를 위해 트랜잭션을 관리하도록하고 @remigio가 제안한 내용을 변경해야합니다. 당신. 두 번째 방법이 더 나은 것으로 보입니다

0

remigio 님의 의견은 정확합니다. @Stateless 세션 빈은 javax.ejb. @ TransactionAttribute를 사용하여 트랜잭션 경계를 제어합니다. 주석이 없으면 모든 public 메소드가 TransactionAttribute.REQUIRED입니다. 자세한 내용은 http://download.oracle.com/otndocs/jcp/ejb-3_0-fr-eval-oth-JSpec/ (ejb-3_0-fr-spec-ejbcore.pdf)을 참조하십시오.

UserTransaction은 @Stateless 세션 빈에서는 사용되지 않지만, 메소드 호출 자체보다 더 넓은 트랜잭션 창을 구분하기 위해 빈을 호출하는 클라이언트에서 사용됩니다.

+0

당신은 Stateless 세션 빈에서 결코 사용되지 않는 UserTransaction이 맞습니다. 그러나 더 넓은 트랜잭션 창을 필요로하는 클라이언트에 대해서는 stateful 세션 빈을 사용하고 @PersistenceContext (PersistenceContextType.Extended)를 삽입합니다. 세션 경계 내에 트랜잭션 경계 설정 정책을 캡슐화하고이를 클라이언트가 관리하도록 노출하고 싶지는 않습니다. – Sam

관련 문제