3

JNDI 経由で検索するエンティティ Bean にワーク マネージャーを構成しました。変更の背後にあるアイデアは、時間がかかる可能性があるため、検証の一部をマルチスレッド化することでしたが、これには現在のトランザクションへのアクセスが必要です。

私のテストでは、ワーカー スレッドではトランザクションにアクセスできないようです。ワーカー スレッドでトランザクションにアクセスしたいのですが、できますか?

作業がスケジュールされたときに XID オブジェクトが渡されるこのExecutionContextに似た、つまり現在のトランザクションを継承することを望んでいました。WebLogic はこれをサポートしていますか?

これは私がやったことです:

weblogic-ejb-jar.xml次のように、ワーク マネージャーの定義を追加しました。

  <work-manager>
    <name>wm/EJBWorkManager</name>
    <min-threads-constraint>
      <name>EJBWorkManager_MinThreadCount</name>
      <count>5</count>
    </min-threads-constraint>
  </work-manager>

の Bean 定義に関する参照を追加しましたejb-jar.xml

  <resource-ref>
    <description>Work Manager allows multi-threading of defined units of work.</description>
    <res-ref-name>wm/EJBWorkManager</res-ref-name>
    <res-type>commonj.work.WorkManager</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

次に、コードでワーク マネージャーを検索し、いくつかの作業を実行するようにスケジュールしました。

weblogic.transaction.Transaction tx = ( weblogic.transaction.Transaction ) weblogic.transaction.TransactionHelper.getTransactionHelper().getTransaction();
log.info( tx != null ? tx.getXid().toString() : "No Transaction" );
try {
  InitialContext initialContext = new InitialContext();
  WorkManager workManager = ( WorkManager ) initialContext.lookup( "java:comp/env/wm/EJBWorkManager" );
  List<WorkItem> workItems = new ArrayList<WorkItem>(); 
  for ( int i = 0; i < 2; i++ ) {
    Work work = new Work() {
      public void run() {
        weblogic.transaction.Transaction tx = ( weblogic.transaction.Transaction ) weblogic.transaction.TransactionHelper.getTransactionHelper().getTransaction();
        log.info( tx != null ? tx.getXid().toString() : "No Transaction" );
      }
      public boolean isDaemon() {
        return false;
      }
      public void release() {
      }
    };
    workItems.add( workManager.schedule( work ) );
  }
  workManager.waitForAll( workItems, WorkManager.INDEFINITE );
} catch ( NamingException e ) {
  throw new RemoteException( "Error", e );
} catch ( IllegalArgumentException e ) {
  throw new RemoteException( "Error", e );
} catch ( InterruptedException e ) {
  throw new RemoteException( "Error", e );
} catch ( WorkException e ) {
  throw new RemoteException( "Error", e );
}

私が得る出力は次のとおりです。これは、生成されたスレッドでトランザクションが利用できないことを示しています。このトランザクションをワーカー スレッドで共有することは可能ですか? 私は彼らがこれを JCA 1.5 (JSR 112) の一部として行ったと思っていました。

16 [[ACTIVE] ExecuteThread: '1' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - BEA1-0474BACB4707C088B359
16 [[STANDBY] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - No Transaction
16 [[STANDBY] ExecuteThread: '10' for queue: 'weblogic.kernel.Default (self-tuning)'] INFO com.tracegroup.isys.weblogic.beans.session.SimpleEJB - No Transaction

編集: weblogic.connector.work.WorkManager と javax.resource.spi.work.WorkManager も使用してみましたが、JNDI ルックアップの実行時にこれらが返されませんでした。これらは、ExecutionContext をワーク マネージャーに渡して、XID を与えることを可能にしているように見えます。これらのクラスを使用した最初のテストでは、うまくいかないように見えました。おそらく私は何かを逃しましたか?

4

1 に答える 1

3

Oracleサポートコールからの公式の言葉:

不可/対応しています。JTA にはシングル スレッド モデルがあります。

1 つのトランザクションに複数のスレッドが関与する可能性がある 1 つのケースは、リモート サーバーへの呼び出しがある場合です。リモートサーバーは、サブコーディネーターとして登録されています。それでも、制御の全体的なフローはシングル スレッドであるため、このモデルをスレッドのローカル プールに拡張しても何も得られません。

于 2012-12-06T15:51:34.907 に答える