0

グローバル tx でいくつかの作業を実行する必要がある状況があります。

このため、jta entityManager を取得するために、persistence.xml で次の PersistenceUnit を定義しています。

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

ここで永続化するために、次のように進めようとしました #1:

    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)

先に進む前にユーザートランザクションを開始したときも同じ理由がありました。

だから私は別のアプローチ#2を試しました:

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

この種の作品ですが、これが正しいアプローチであるかどうかはわかりません。

最初のケースで物事がうまくいかない理由と、2番目のアプローチがうまくいくかどうか、誰かが私を助けることができれば感謝しますか?

4

3 に答える 3

2

最初のアプローチは機能するはずです。トランザクションについてEclipselinkに伝える構成設定が欠落している可能性があります。http://eclipse.org/eclipselink/documentation/2.4/jpa/extensions/p_target_server.htmで説明されているターゲット サーバー プロパティを指定していることを確認します 。 これは、トランザクション マネージャーを取得し、アクティブなトランザクションに登録するために使用されます。

トランザクションに正しく登録されたら、UnitOfWork で commit を直接呼び出す必要はありません。

于 2012-11-03T15:59:11.673 に答える
1

コードの早い段階で、mXAEntityManager を次のような SE の方法でインスタンス化したと仮定します。

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

EntityManager mXAEntityManager = entityManagerFactory.createEntityManager();

これは、アプリケーション サーバーにデプロイされた EE アプリケーションでは機能しません。これらの 2 行を、次のような依存性注入に置き換える必要があります。

@PersistenceContext(unitName = "resubEclipselink")

EntityManager mXAEntityManager;

必要なすべてのトランザクション管理を伴う永続コンテキスト (mXAEntityManager) をコンテナに注入できるようにします。したがって、すでに次のように設定されているデフォルトを台無しにしない限り、flush() no begin() no commit() 呼び出しはもう必要ありません。

@PersistenceContext(ユニット名 = "resubEclipselink"、タイプ = PersistenceContextType.TRANSACTION)

EntityManager mXAEntityManager;

次のように、セッション Bean に既に設定されている別のデフォルトと同様に:

@TransactionAttribute(TransactionAttributeType.REQUIRED)

これらのデフォルトは、パラダイム「例外による構成」に従って EE アプリケーションを開発するものであることを忘れないでください。

于 2012-11-04T04:54:19.857 に答える
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();                   
  }

前に述べたように、私はこのアプローチにあまり自信がないので、誰かがこれをレビューして、このアプローチに欠陥があるかどうかを教えていただければ幸いです...

于 2012-11-05T07:29:34.550 に答える