2012-11-03 5 views
0

글로벌 tx에서 일부 작업을 수행해야하는 경우가 있습니다.XA 트랜잭션에서 작업 수행

이러한 이유 때문에 jta entityManager를 얻으려면 내 persistence.xml에 다음 PersistenceUnit이 정의되어 있습니다. 나는 사용자 트랜잭션 이전을 시작할 때

if(isXA()){ 
     mXAEntityManager.persist(entity); 
     mXAEntityManager.flush(); 
    } 

것들 내가 같은 이유를 가지고

javax.persistence.TransactionRequiredException: 
Exception Description: No transaction is currently active 
    at  
org.eclipse.persistence.internal.jpa.transaction.EntityTransactionWrapper.throwCheckTransactionFailedException(EntityTransactionWrapper.java:113) 

예외와 함께 실패 :

<persistence-unit name="resubEclipselink" transaction-type="JTA"> 
    <jta-data-source>jdbc/XADataSource</jta-data-source> 
    ... 
</persistence-unit> 
이제

내가 같이 진행하려고 지속하기는 # 1 다음 진행.

그래서 나는 또 다른 접근 방법 # 2 시도 :

// get the transactional unit of work or null. 
UnitOfWork uow = mEntityManager.getUnitOfWork(); 
    uow.registerObject(entity); 
uow.writeChanges(); 
uow.commit();   

작품이 일종의 그러나 이것은 올바른 방법입니다 있는지 확실하지 않다.

누군가가 첫 번째 경우에 작동하지 않는 이유와 두 번째 접근 방식이 정상적으로 작동하는 이유를 도와 주시면 감사하겠습니다.

답변

2

첫 번째 접근 방식이 효과적 일 수 있습니다. 구성 설정에서 Eclipselink에 트랜잭션에 대해 알려주지 않을 수 있습니다. 여기에 설명 된 대상 서버 속성을 지정했는지 확인하십시오. http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_server.htm 트랜잭션 관리자를 가져와 활성 트랜잭션에 등록하는 데 사용됩니다.

트랜잭션에 올바르게 등록되면 UnitOfWork에서 직접 커밋을 호출 할 필요가 없습니다.

1

나는 당신이 SE 방법과 같이 mXAEntityManager을 인스턴스화 코드에서 이전 가정 :

의 EntityManagerFactory의 EntityManagerFactory = Persistence.createEntityManagerFactory ("resubEclipselink");

EntityManager mXAEntityManager = entityManagerFactory.createEntityManager();

응용 프로그램 서버에 배포 된 EE 응용 프로그램에서는 작동하지 않습니다. 이 같은 의존성 주입 그 2 개 라인을 교체해야

@PersistenceContext (unitName = "resubEclipselink")

의 EntityManager mXAEntityManager;

컨테이너가 필요한 모든 트랜잭션 관리와 함께 지속성 컨텍스트 (mXAEntityManager)를 삽입 할 수 있도록합니다. 따라서 이미 다음과 같이 설정된 기본값을 사용하지 않는 한 flush()와 no begin()은 더 이상 필요하지 않습니다.

@PersistenceContext (unitName) = "resubEclipselink", type = PersistenceContextType.TRANSACTION)

EntityManager mXAEntityManager;

뿐만 아니라 이미이 같은 세션 빈 설정 다른 기본 :

@TransactionAttribute (TransactionAttributeType.REQUIRED)

이 기본값은 다음 EE 응용 프로그램을 개발 만드는 것입니다 기억 패러다임 "예외로 구성".

+0

설명해 주셔서 감사합니다. 정확히 엔 엔티티 관리자를 얻으려고합니다. 이제는 컨테이너 관리 엔티티 관리자가 필요할 것이므로 제안한 방식으로 인수해야 함을 이해합니다. 그러나 불행히도 내 시나리오는 다른 조건에 따라 트랜잭션 경계를 결정해야하는 방식으로 실행됩니다. 또한 나는 세션 bean을 통해 주입하는 것이 나를 위해 너무 실행 가능하지 않을 수도 있도록 내 통제에 실제로 있지 않은 정면 api를 통해 전화를 받는다. –

0

내 시나리오는 다른 조건에 따라 트랜잭션 경계를 결정해야하는 방식으로 실행됩니다.

기본적으로 응용 프로그램 관리 엔티티 관리자를 전역 tx에 등록시키고 전역 tx의 일부로 일부 작업 단위를 수행해야합니다. 그래서 실제로 엔티티 관리자를 가져 와서 ExternalTransactionController를 사용하도록 설정했습니다. 다음

  if(isXA){ 
        this.mEntityManager = JpaHelper.getEntityManager(Persistence.createEntityManagerFactory(XA_PU). 

              createEntityManager()); 

        this.mServerSession = this.mEntityManager.getServerSession(); 
        this.mServerSession.getLogin().setUsesExternalTransactionController(true); 
        this.mServerSession.getLogin().setUsesExternalConnectionPooling(true); 
      }else{ 
        this.mEntityManager = JpaHelper.getEntityManager(Persistence.createEntityManagerFactory(RESORUCE_LOCAL_PU). 
                                  createEntityManager()); 

        this.mEntityTransaction = this.mEntityManager.getTransaction(); 
        this.mServerSession = this.mEntityManager.getServerSession(); 
      } 

및 취득과 같은 작업 단위를 수행

... 내가 전에 언급 한 바와 같이

// get the transactional unit of work or null. 
    UnitOfWork uow = mEntityManager.getUnitOfWork(); 

    // resource-local em 
    if(uow == null){ 
      mEntityTransaction.begin(); 
      mEntityManager.persist(entity); 
      mEntityTransaction.commit(); 
    }else{     
      uow.registerObject(entity); 
      uow.writeChanges(); 
      uow.commit();     
    } 

, 나는이 방법에 대해 너무 자신이없는 나는 누군가가이 문제를 검토 할 수 있다면 그래서 정말 감사합니다 이 방법에 몇 가지 결함이있는 경우 알려주십시오 ...