Red Hat Training

A Red Hat training course is available for Red Hat JBoss Enterprise Application Platform

8.7.4. EJB 呼び出しのトランザクション動作

サーバー間の呼び出し

分散 JBoss EAP アプリケーションのトランザクション属性は、アプリケーションが同じサーバー上で呼び出されているかのように処理する必要があります。トランザクションを中止するには、別のインターフェイスを使用して宛先メソッドに REQUIRES_NEW のマークを付ける必要があります。

備考
両方のサーバーが JBoss EAP 6 の場合、JBoss EAP 6 はサーバー間 EJB 呼び出しでのトランザクション伝播に Java Transaction Services (JTS) を必要としません。JBossEJB クライアント API ライブラリーはそれ自体を処理します。

クライアント側の呼び出し

JBoss EAP 6 スタンドアロンクライアントで EJB セッション Bean を呼び出すには、EJB プロキシーまたは UserTransaction が使用されている間、クライアントは InitialContext オブジェクトへの参照を持っている必要があります。また、EJB プロキシーまたは UserTransaction が使用されている間、InitialContext オブジェクトを開いたままにしておくことも重要です。接続の制御は、InitialContext によってプロパティーを使用して作成されたクラス内で行われます。

次の例は、InitialContext オブジェクトへの参照を保持する EJB クライアント API を示しています。

例8.6 InitialContext オブジェクトを参照する EJB クライアント API

package org.jboss.as.quickstarts.ejb.multi.server;

import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.naming.Context;
import javax.naming.InitialContext;

import org.jboss.as.quickstarts.ejb.multi.server.app.MainApp;
import org.jboss.ejb.client.ContextSelector;
import org.jboss.ejb.client.EJBClientConfiguration;
import org.jboss.ejb.client.EJBClientContext;
import org.jboss.ejb.client.PropertiesBasedEJBClientConfiguration;
import org.jboss.ejb.client.remoting.ConfigBasedEJBClientContextSelector;

public class Client {

/**
* @param args no args needed
* @throws Exception
*/
    public static void main(String[] args) throws Exception {
        // suppress output of client messages
        Logger.getLogger("org.jboss").setLevel(Level.OFF);
        Logger.getLogger("org.xnio").setLevel(Level.OFF);
        
        Properties p = new Properties();
        p.put("remote.connectionprovider.create.options.org.xnio.Options.SSL_ENABLED", "false");
        p.put("remote.connections", "one");
        p.put("remote.connection.one.port", "4447");
        p.put("remote.connection.one.host", "localhost");
        p.put("remote.connection.one.username", "quickuser");
        p.put("remote.connection.one.password", "quick-123");

        EJBClientConfiguration cc = new PropertiesBasedEJBClientConfiguration(p);
        ContextSelector<EJBClientContext> selector = new ConfigBasedEJBClientContextSelector(cc);
        EJBClientContext.setSelector(selector);

        Properties props = new Properties();
        props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
        InitialContext context = new InitialContext(props);

        
        final String rcal = "ejb:jboss-ejb-multi-server-app-main/ejb//" + ("MainAppBean") + "!" + MainApp.class.getName();
        final MainApp remote = (MainApp) context.lookup(rcal);
        final String result = remote.invokeAll("Client call at "+new Date());

        System.out.println("InvokeAll succeed: "+result);
    }

}
注記
クライアントでの UserTransaction 参照の取得は、スコープ付き EJB クライアントコンテキストを使用するシナリオ、および リモートネーミング プロトコルを使用する呼び出しではサポートされていません。これは、これらのシナリオでは、InitialContext が独自の EJB クライアントコンテキストインスタンスをカプセル化するためです。これは、EJBClient クラスの静的メソッドを使用してアクセスすることはできません。いつEJBClient.getUserTransaction()が呼び出されると、デフォルトの (グローバル)EJB クライアントコンテキスト (初期化されていない可能性があります) からではなく、目的のコンテキストからトランザクションを返します。

クライアント側の UserTransaction リファレンス

次の例は、スタンドアロンクライアントで UserTransaction 参照を取得する方法を示しています。

例8.7 UserTransaction オブジェクトを参照するスタンドアロンクライアント

import org.jboss.ejb.client.EJBClient;
import javax.transaction.UserTransaction;
.
.
    Context context=null;
    UserTransaction tx=null;
    try {
      Properties props = new Properties();
      // REMEMBER: there must be a jboss-ejb-client.properties with the connection parameter
      //           in the clients classpath
      props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
      context = new InitialContext(props);  
      System.out.println("\n\tGot initial Context: "+context);
      tx=EJBClient.getUserTransaction("yourServerName");
      System.out.println("UserTransaction = "+tx.getStatus());
      tx.begin();
      // do some work
      ...
    }catch (Exception e) {
      e.printStackTrace();
      tx.rollback();
    }finally{
      if(context != null) {
        context.close();
      }
    }

注記
クライアント側で UserTransaction 参照を取得するには;次のシステムプロパティー -Djboss.node.name=yourServerName を使用してサーバーを起動し、クライアント側で次のように使用します。
tx=EJBClient.getUserTransaction("yourServerName");
yourServerName をサーバーの名前に置き換えます。ユーザートランザクションがノードで開始された場合、すべての呼び出しはノードでスティッキーであり、ノードには必要なすべての EJB が必要です。リモートネーミングプロトコルとスコープコンテキストで UserTransaction を使用することはできません。