ヘッダーをスキップ

Oracle Containers for J2EE Enterprise JavaBeans開発者ガイド
10g(10.1.3.1.0)

B31852-03
目次
目次
索引
索引

戻る 次へ

21 トランザクション・サービスの構成

この章の内容は次のとおりです。

詳細は、次を参照してください。

EJB 3.0トランザクション管理の構成

EJB 3.0 EJBトランザクション管理を構成するには、アノテーション(「アノテーションの使用方法」を参照)またはデプロイXML(「デプロイXMLの使用方法」を参照)を使用します。


注意

EJB 3.0エンティティは、トランザクション管理タイプで構成できません。EJB 3.0エンティティは、コール元のトランザクション・コンテキスト内で実行されます。 


詳細は、次を参照してください。

アノテーションの使用方法

例21-1に示すように、トランザクション管理は@TransactionManagementアノテーションの属性valueを使用して構成できます。次のいずれかの値を指定できます。

@TransactionManagementアノテーションは、クラス・レベルで適用します。

例21-1    EJB 3.0セッションBeanのトランザクション管理の構成

import javax.ejb.Stateful
import javax.annotation.PostConstruct;
import javax.ejb.Remove;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;

@Stateful
@TransactionManagement(value=TransactionManagementType.CONTAINER)
public class CartBean implements Cart {
    private ArrayList items;

    @PostConstruct
    public void initialize() {
        items = new ArrayList();
    }

    @Remove
    public void finishedShipping() {
        // Release any resources.
    }

    public void addItem(String item) {
        items.add(item);
    }

    public void removeItem(String item) {
        items.remove(item);
    }
}

 

デプロイXMLの使用方法

EJB 3.0 EJBでは、EJB 2.1 Enterprise Beanと同様に、ejb-jar.xmlファイルでトランザクション管理を構成します(「デプロイXMLの使用方法」を参照)。

EJB 3.0トランザクション属性の構成

クライアントがコンテナ管理のトランザクション用に構成されたEJB 3.0 Enterprise Beanのメソッドを起動したときにコンテナがトランザクションを管理する方法を構成するには、アノテーション(「アノテーションの使用方法」を参照)またはデプロイXML
「デプロイXMLの使用方法」を参照)を使用します。

詳細は、次を参照してください。

アノテーションの使用方法

例21-2に示すように、トランザクション管理は@TransactionAttributeアノテーションの属性valueを使用して構成できます。表21-1に、ユーザーが指定できるTransactionAttributeTypeの値と、メソッドの起動時にクライアント管理のトランザクションが存在するかどうかに応じて変化するコンテナの対応動作を示します。

表21-1    @TransactionAttributeのTransactionAttributeTypeの値 
トランザクション属性  クライアント管理のトランザクションが存在  クライアント管理のトランザクションが存在しない 

NOT_SUPPORTED 

コンテナはクライアント・トランザクションを一時停止します。 

トランザクションを使用しません。 

SUPPORTS 

クライアント管理のトランザクションを使用します。 

トランザクションを使用しません。 

REQUIRED1 

クライアント管理のトランザクションを使用します。 

コンテナは新規トランザクションを開始します。 

REQUIRES_NEW 

クライアント管理のトランザクションを使用します。 

コンテナは新規トランザクションを開始します。 

MANDATORY 

クライアント管理のトランザクションを使用します。 

例外が発生します。 

NEVER 

例外が発生します。 

トランザクションを使用しません。 

1 デフォルト。

@TransactionAttributeアノテーションをクラス・レベルで適用すると、Enterprise Beanのすべてのビジネス・メソッドに対応するデフォルトのトランザクション属性を指定できます。このアノテーションをメソッド・レベルで適用すると、そのメソッドのトランザクション属性を指定できます。メソッド・レベルで適用されたアノテーションは、そのメソッドのクラス・レベルのアノテーション(存在する場合)をオーバーライドします。

例21-2    EJB 3.0セッションBeanのトランザクション属性の構成

import javax.ejb.Stateful;
import javax.annotation.PostConstruct;
import javax.ejb.Remove;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.ejb.TransactionAttribute;
import static javax.ejb.TransactionAttributeType.REQUIRED;
import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;
import com.acme.Cart;

@Stateful
@TransactionManagement(value=TransactionManagementType.CONTAINER)
@TransactionAttribute(value=REQUIRED)
public class CartBean implements Cart {
    private ArrayList items;

    @PostConstruct
    public void initialize() {
        items = new ArrayList();
    }

    @Remove
    @TransactionAttribute(value=REQUIRES_NEW)
    public void finishedShipping() {
        // Release any resources.
    }

    public void addItem(String item) {
        items.add(item);
    }

    public void removeItem(String item) {
        items.remove(item);
    }
}

 

デプロイXMLの使用方法

EJB 3.0 Enterprise Beanでは、EJB 2.1 Enterprise Beanと同様に、orion-ejb-jar.xmlファイルでトランザクション属性を構成します(「デプロイXMLの使用方法」を参照)。

EJB 2.1トランザクション管理の構成

特定のEJB 2.1 Enterprise Beanに関連するトランザクションの管理方法を構成できます
「デプロイXMLの使用方法」を参照)。


注意

EJB 2.1エンティティBeanは、常にコンテナ管理のトランザクション境界を使用する必要があります。EJB 2.1エンティティBeanは、Bean管理のトランザクション境界で指定できません。 


詳細は、次を参照してください。

デプロイXMLの使用方法

トランザクション管理を構成するには、例21-3に示すように、ejb-jar.xmlファイルの<transaction-type>サブ要素を使用します。

有効な値は、ContainerまたはBeanです。デフォルトはContainerです。

例21-3    EJB 2.1セッションBeanのトランザクション管理の構成

<enterprise-beans>
    <session>
        <display-name>A Credit-Service Bean</display-name>
        <ejb-name>CreditService</ejb-name>
        <home>creditService.ejb.CreditServiceHome</home>
        <remote>creditService.ejb.CreditServiceRemote</remote>
        <ejb-class>creditService.ejb.CreditServiceBean</ejb-class>
        <session-type>Stateless</session-type>
        <transaction-type>Container</transaction-type>
        ...
    </session>
...
</enterprise-beans>

 

すべてのセッションBean、エンティティBeanおよびメッセージドリブンBeanを対象に<transaction-type>を構成できます。ただし、EJB 2.1エンティティBeanに対しては、<transaction-type>Containerとしてのみ構成できます。

EJB 2.1トランザクション属性の構成

コンテナ管理のトランザクションを使用するEnterprise Beanでは、クライアントがBeanメソッドを起動したときにコンテナがトランザクションを管理する方法を構成できます
「デプロイXMLの使用方法」を参照)。

詳細は、次を参照してください。

デプロイXMLの使用方法

クライアントがBeanメソッドを起動したときにコンテナがトランザクションを管理する方法を構成するには、例21-4に示すように、ejb-jar.xmlファイルの<assembly-descriptor>のサブ要素<container-transaction>を使用します。

例21-4    EJB 2.1セッションBeanのトランザクション属性の構成

<assembly-descriptor>
    <container-transaction>
        <method>
            <ejb-name>CreditService</ejb-name>
            <method-name>setLimit</method-name>
            <method-params>
                <method-param>int</method-param>
            </method-params>
        </method>
        <trans-attribute>Required</trans-attribute>
    </container-transaction>
...
</assembly-descriptor>

 

<container-transaction>要素には、1つ以上の<method>要素と1つの<trans-attribute>要素が含まれます。<trans-attribute>要素は、すべての<method>要素に適用されます。メソッドは、名前で、または名前とパラメータ(シグネチャ)で指定できます。または、ワイルドカード<method-name>*</method-name>を使用して、特定のEnterprise Beanのすべてのメソッドを指定できます。

表21-2に、ユーザーが指定できる<trans-attribute>要素の値と、メソッドの起動時にクライアント管理のトランザクションが存在するかどうかに応じて変化するコンテナの対応動作を示します。

表21-2    <trans-attribute>要素の有効な値 
トランザクション属性  クライアント管理のトランザクションが存在  クライアント管理のトランザクションが存在しない 

NotSupported1 

コンテナはクライアント・トランザクションを一時停止します。 

トランザクションを使用しません。 

Supports2 

クライアント管理のトランザクションを使用します。 

トランザクションを使用しません。 

Required3 

クライアント管理のトランザクションを使用します。 

コンテナは新規トランザクションを開始します。 

RequiresNew 

コンテナはクライアント・トランザクションを一時停止して新規トランザクションを作成します。 

コンテナは新規トランザクションを開始します。 

Mandatory 

クライアント管理のトランザクションを使用します。 

例外が発生します。 

Never 

例外が発生します。 

トランザクションを使用しません。 

1 EJB 2.1メッセージドリブンBeanのデフォルト。

2 EJB 2.1セッションBeanおよびBMPエンティティBeanのデフォルト。

3 EJB 2.1 CMPエンティティBeanのデフォルト。

トランザクション・タイムアウトの構成

アプリケーション・パフォーマンスを向上させるために、OC4Jがトランザクションのコミットまたはロールバックを待機する時間の長さを決定するトランザクション・タイムアウトを構成できます。

この項の内容は次のとおりです。

グローバル・トランザクション・タイムアウトの構成

OC4JがセッションおよびエンティティBeanについて管理するすべてのトランザクションにグローバルに適用するトランザクション・タイムアウトを設定できます。

次の方法でグローバル・トランザクション・タイムアウトを構成できます。

Application Server Controlコンソールの使用方法

Application Server Controlコンソール(「Oracle Enterprise Manager 10g Application Server Controlの使用方法」を参照)を使用した場合は、JTAResource MBeanの属性transactionTimeoutを設定できます。

詳細は、『Oracle Containers for J2EEサービス・ガイド』の「OC4Jトランザクション・マネージャの構成」を参照してください。

デプロイXMLの使用方法

<OC4J_HOME>¥j2ee¥home¥config¥transaction-manager.xmlファイルで、<transaction-manager>要素のtransaction-timeout属性を使用してグローバル・トランザクション・タイムアウトを設定します。

たとえば、グローバル・トランザクション・タイムアウトを180秒に設定する場合は、次のようにします。

<transaction-manager ...  transaction-timeout="180"
  ...
</transaction-manager>

この方法を使用してこのプロパティを変更する場合は、OC4Jを再起動して変更を適用する必要があります。または、Application Server Controlコンソールを使用して、OC4Jを再起動せずにこのパラメータを動的に変更できます(「Application Server Controlコンソールの使用方法」を参照)。

セッションBeanのトランザクション・タイムアウトの構成

各セッションBeanのトランザクション・タイムアウトは、OC4J固有のアノテーション
「アノテーションの使用方法」を参照)またはorion-ejb-jar.xmlファイル(「デプロイXMLの使用方法」を参照)を使用して指定できます。

セッションBeanのトランザクション・タイムアウトは、グローバル・トランザクション・タイムアウトをオーバーライドします(「グローバル・トランザクション・タイムアウトの構成」を参照)。

デプロイXMLの構成は、アノテーションを使用して設定された対応する構成をオーバーライドします。

アノテーションの使用方法

EJB 3.0セッションBeanのトランザクション・タイムアウトは、次のOC4J固有のアノテーションとその属性を使用して指定できます。

これらの属性の詳細は、表A-1を参照してください。

例21-5に、@StatelessDeploymentアノテーションを使用してEJB 3.0ステートレス・セッションBeanでこれらの属性を構成する方法を示します。

例21-5    @StatelessDeploymentのtransactionTimeout属性

import javax.ejb.Stateless;
import oracle.j2ee.ejb.StatelessDeployment;

@Stateless
@StatelessDeployment(transactionTimeout=10)
public class HelloWorldBean implements HelloWorld {
    public void sayHello(String name) {
        System.out.println("Hello " + name + " from first EJB3.0");
    }
}

 

デプロイXMLの使用方法

orion-ejb-jar.xmlファイルで、<session-deployment>要素のtransaction-timeout属性を使用してセッションBeanのトランザクション・タイムアウトを設定します。

たとえば、グローバル・トランザクション・タイムアウトを180秒に設定する場合は、次のようにします。

<session-deployment ...  transaction-timeout="180"
  ...
</session-deployment>

この方法を使用してこのプロパティを変更する場合は、OC4Jを再起動して変更を適用する必要があります。

メッセージドリブンBeanのトランザクション・タイムアウトの構成

メッセージドリブンBeanのトランザクション・タイムアウトは、OC4J固有のアノテーション(「アノテーションの使用方法」を参照)またはorion-ejb-jar.xmlファイル(「デプロイXMLの使用方法」を参照)を使用して構成できます。

グローバル・トランザクション・タイムアウト(「グローバル・トランザクション・タイムアウトの構成」を参照)はメッセージドリブンBeanに適用されないため、メッセージドリブンBeanのデフォルトのトランザクション・タイムアウトを変更する場合は、各メッセージドリブンBeanのトランザクション・タイムアウトを構成する必要があります。

使用するメッセージ・サービス・プロバイダのタイプ(「MDBで使用できるメッセージ・サービス・プロバイダ」を参照)は、次のようにトランザクション・タイムアウト・オプションに影響します。

デプロイXMLの構成は、アノテーションを使用して設定された対応する構成をオーバーライドします。

アノテーションの使用方法

EJB 3.0セッションBeanのトランザクション・タイムアウトは、OC4J固有のアノテーション@MessageDrivenDeploymentの属性transactionTimeoutを使用して指定できます。

この属性の詳細は、表A-3を参照してください。

例21-6に、@MessageDrivenDeploymentアノテーションを使用してEJB 3.0メッセージドリブンBeanでこの属性を構成する方法を示します。

例21-6    @MessageDrivenDeployment

import javax.ejb.MessageDriven;
import oracle.j2ee.ejb.MessageDrivenDeployment;
import javax.ejb.ActivationConfigProperty;
import javax.annotation.Resource;

@MessageDriven(
    activationConfig = {
        @ActivationConfigProperty(
            propertyName="messageListenerInterface",
            propertyValue="javax.jms.MessageListener"),
        @ActivationConfigProperty(
            propertyName="connectionFactoryJndiName",
            propertyValue="jms/TopicConnectionFactory"),
         @ActivationConfigProperty(
            propertyName="destinationName",
            propertyValue="jms/demoTopic"),
         @ActivationConfigProperty(
            propertyName="destinationType",
            propertyValue="javax.jms.Topic"),
         @ActivationConfigProperty(
            propertyName="messageSelector",
            propertyValue="RECIPIENT = 'MDB'")
    }
)
@MessageDrivenDeployment(transactionTimeout=10)
public class MessageLogger implements MessageListener, TimedObject {
    @Resource javax.ejb.MessageDrivenContext mc;

    public void onMessage(Message message) {
    ...
    }

    public void ejbTimeout(Timer timer) {
    ...
    }
}

デプロイXMLの使用方法

orion-ejb-jar.xmlファイルで、トランザクション・タイムアウトを設定します。この値の構成方法は、使用しているメッセージドリブン・プロバイダのタイプによって決まります。

J2CA以外のアダプタ・メッセージ・サービス・プロバイダ

OEMS JMSやOEMS JMSデータベースなどのJ2CA以外のアダプタ・メッセージ・サービス・プロバイダを使用している場合は、<message-driven-deployment>要素のtransaction-timeout属性を使用します。

たとえば、OEMS JMSまたはOEMS JMSデータベースを使用していて、トランザクション・タイムアウトを180秒に設定する場合は、次のようにします。

<message-driven-deployment ...  transaction-timeout="180"
  ...
</message-driven-deployment>

J2CAアダプタ・メッセージ・サービス・プロバイダ

J2CAアダプタ・メッセージ・サービス・プロバイダを使用している場合は、<config-property>要素を使用して、transactionTimeout構成プロパティを設定します。

たとえば、J2CAアダプタ・メッセージ・サービス・プロバイダを使用していて、トランザクション・タイムアウトを180秒に設定する場合は、次のようにします。

<message-driven-deployment ... >
...
    <config-property>
        <config-property-name>transactionTimeout</config-property-name>
        <config-property-value>180</config-property-value>
    </config-property>
...
</message-driven-deployment>

どちらの場合も、このメソッドを使用してこのプロパティを変更する場合は、OC4Jを再起動して変更を適用する必要があります。

トランザクションのベスト・プラクティス

この項では、EJBアプリケーションのトランザクションを使用する次のような推奨アプローチを説明します。

データソース接続でのコンテナ管理のトランザクションの使用方法

コンテナ管理のトランザクションを使用していて、データソース接続を使用する場合は、トランザクションのコミットまで接続が解放されないことに注意してください。このことは、ループ内でデータソース接続を使用している場合に特に重要です。この場合は、ループの外部で接続を取得および解放して、接続プールが不注意で使い果されるのを回避する必要があります。

コンテナ管理のトランザクションを構成するセッションBeanについて考えます。このセッションBeanには、例21-7に示すようにメソッドrunQueryConnectionEveryTimeがあります。このメソッドがコールされると、コンテナ管理のトランザクションが開かれます。forループを反復するたびに、接続が取得されて閉じられます。ただし、閉じられた接続は、メソッドが返され、コンテナ管理のトランザクションがコミットするまで解放されません。反復の回数に応じて、この設計では接続プールが使い果される場合があります。

この問題を回避するには、例21-8に示すように、ループの外部で接続を取得し、閉じる必要があります。これにより、コンテナ管理のトランザクションがコミットするまで1つの接続しか保持されないようにできます。

例21-7    不正な例: コミットまで複数の接続が保持される

public static long runQueryConnectionEveryTime (int count) {
    InitialContext ic = new InitialContext();
    DataSource ds = (DataSource) ic.lookup("jdbc/OracleDS");

    for (int i = 0; i < count; i++) {
        Connection con = ds.getConnection(); //connection created inside loop

        PreparedStatement ps = con.prepareStatement(
            "select AAA_ID, AAA_A FROM AAA_TABLE where AAA_ID = ? ");

        OracleStatement os = (OracleStatement)ps;
        os.defineColumnType(1, Types.BIGINT);
        ps.setLong(1, i);
        ResultSet rs = ps.executeQuery();
        rs.close();
        ps.close();

        con.close(); //connection closed inside loop
    }
}

例21-8    正しい例: コミットまで保持される接続数は1つのみ

public static long runQueryConnectionEveryTime (int count) {
    InitialContext ic = new InitialContext();
    DataSource ds = (DataSource) ic.lookup("jdbc/OracleDS");

    Connection con = ds.getConnection(); //connection created outside loop

    for (int i = 0; i < count; i++) {
        PreparedStatement ps = con.prepareStatement(
            "select AAA_ID, AAA_A FROM AAA_TABLE where AAA_ID = ? ");

        OracleStatement os = (OracleStatement)ps;
        os.defineColumnType(1, Types.BIGINT);
        ps.setLong(1, i);
        ResultSet rs = ps.executeQuery();
        rs.close();
        ps.close();
    }

    con.close(); //connection closed outside loop
}

ロールバック計画の使用方法

コンテナ管理のトランザクション境界のあるEnterprise Beanでは、そのjavax.ejb.EJBContextオブジェクトのsetRollbackOnlyメソッドを使用して、コミットできないようにトランザクションをマークできます。

通常は、この処理を行って、アプリケーション例外が原因でコンテナがトランザクションを自動的にロールバックしない場合にアプリケーション例外をスローする前に、データ整合性を保護します。

たとえば、1つのアカウントを借方計上し、別のアカウントに貸方計上するAccountTransfer Beanは、借方計上を正常に実行し、貸方操作で障害が発生した場合に、トランザクションにロールバックのマークを付けることができます。

詳細は、次を参照してください。


戻る 次へ
Oracle
Copyright © 2002, 2008 Oracle Corporation.

All Rights Reserved.
目次
目次
索引
索引