Oracle Containers for J2EE Enterprise JavaBeans開発者ガイド 10g(10.1.3.1.0) B31852-03 |
|
この章の内容は次のとおりです。
詳細は、次を参照してください。
EJB 3.0 EJBトランザクション管理を構成するには、アノテーション(「アノテーションの使用方法」を参照)またはデプロイXML(「デプロイXMLの使用方法」を参照)を使用します。
詳細は、次を参照してください。
例21-1に示すように、トランザクション管理は@TransactionManagement
アノテーションの属性value
を使用して構成できます。次のいずれかの値を指定できます。
TransactionManagementType.CONTAINER
: コンテナ管理のトランザクション(デフォルト)
TransactionManagementType.BEAN
: Bean管理のトランザクション
@TransactionManagement
アノテーションは、クラス・レベルで適用します。
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);
}
}
EJB 3.0 EJBでは、EJB 2.1 Enterprise Beanと同様に、ejb-jar.xml
ファイルでトランザクション管理を構成します(「デプロイXMLの使用方法」を参照)。
クライアントがコンテナ管理のトランザクション用に構成されたEJB 3.0 Enterprise Beanのメソッドを起動したときにコンテナがトランザクションを管理する方法を構成するには、アノテーション(「アノテーションの使用方法」を参照)またはデプロイXML
(「デプロイXMLの使用方法」を参照)を使用します。
詳細は、次を参照してください。
例21-2に示すように、トランザクション管理は@TransactionAttribute
アノテーションの属性value
を使用して構成できます。表21-1に、ユーザーが指定できるTransactionAttributeType
の値と、メソッドの起動時にクライアント管理のトランザクションが存在するかどうかに応じて変化するコンテナの対応動作を示します。
トランザクション属性 | クライアント管理のトランザクションが存在 | クライアント管理のトランザクションが存在しない |
---|---|---|
|
コンテナはクライアント・トランザクションを一時停止します。 |
トランザクションを使用しません。 |
|
クライアント管理のトランザクションを使用します。 |
トランザクションを使用しません。 |
|
クライアント管理のトランザクションを使用します。 |
コンテナは新規トランザクションを開始します。 |
|
クライアント管理のトランザクションを使用します。 |
コンテナは新規トランザクションを開始します。 |
|
クライアント管理のトランザクションを使用します。 |
例外が発生します。 |
|
例外が発生します。 |
トランザクションを使用しません。 |
1
デフォルト。 |
@TransactionAttribute
アノテーションをクラス・レベルで適用すると、Enterprise 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);
}
}
EJB 3.0 Enterprise Beanでは、EJB 2.1 Enterprise Beanと同様に、orion-ejb-jar.xml
ファイルでトランザクション属性を構成します(「デプロイXMLの使用方法」を参照)。
特定のEJB 2.1 Enterprise Beanに関連するトランザクションの管理方法を構成できます
(「デプロイXMLの使用方法」を参照)。
詳細は、次を参照してください。
トランザクション管理を構成するには、例21-3に示すように、ejb-jar.xml
ファイルの<transaction-type>
サブ要素を使用します。
有効な値は、Container
またはBean
です。デフォルトはContainer
です。
<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
としてのみ構成できます。
コンテナ管理のトランザクションを使用するEnterprise Beanでは、クライアントがBeanメソッドを起動したときにコンテナがトランザクションを管理する方法を構成できます
(「デプロイXMLの使用方法」を参照)。
詳細は、次を参照してください。
クライアントがBeanメソッドを起動したときにコンテナがトランザクションを管理する方法を構成するには、例21-4に示すように、ejb-jar.xml
ファイルの<assembly-descriptor>
のサブ要素<container-transaction>
を使用します。
<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>
要素の値と、メソッドの起動時にクライアント管理のトランザクションが存在するかどうかに応じて変化するコンテナの対応動作を示します。
トランザクション属性 | クライアント管理のトランザクションが存在 | クライアント管理のトランザクションが存在しない |
---|---|---|
|
コンテナはクライアント・トランザクションを一時停止します。 |
トランザクションを使用しません。 |
|
クライアント管理のトランザクションを使用します。 |
トランザクションを使用しません。 |
|
クライアント管理のトランザクションを使用します。 |
コンテナは新規トランザクションを開始します。 |
|
コンテナはクライアント・トランザクションを一時停止して新規トランザクションを作成します。 |
コンテナは新規トランザクションを開始します。 |
|
クライアント管理のトランザクションを使用します。 |
例外が発生します。 |
|
例外が発生します。 |
トランザクションを使用しません。 |
1
EJB 2.1メッセージドリブンBeanのデフォルト。 2 EJB 2.1セッションBeanおよびBMPエンティティBeanのデフォルト。 3 EJB 2.1 CMPエンティティBeanのデフォルト。 |
アプリケーション・パフォーマンスを向上させるために、OC4Jがトランザクションのコミットまたはロールバックを待機する時間の長さを決定するトランザクション・タイムアウトを構成できます。
この項の内容は次のとおりです。
OC4JがセッションおよびエンティティBeanについて管理するすべてのトランザクションにグローバルに適用するトランザクション・タイムアウトを設定できます。
次の方法でグローバル・トランザクション・タイムアウトを構成できます。
Application Server Controlコンソール(「Oracle Enterprise Manager 10g Application Server Controlの使用方法」を参照)を使用した場合は、JTAResource
MBeanの属性transactionTimeout
を設定できます。
詳細は、『Oracle Containers for J2EEサービス・ガイド』の「OC4Jトランザクション・マネージャの構成」を参照してください。
<
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のトランザクション・タイムアウトは、OC4J固有のアノテーション
(「アノテーションの使用方法」を参照)またはorion-ejb-jar.xml
ファイル(「デプロイXMLの使用方法」を参照)を使用して指定できます。
セッションBeanのトランザクション・タイムアウトは、グローバル・トランザクション・タイムアウトをオーバーライドします(「グローバル・トランザクション・タイムアウトの構成」を参照)。
デプロイXMLの構成は、アノテーションを使用して設定された対応する構成をオーバーライドします。
EJB 3.0セッションBeanのトランザクション・タイムアウトは、次のOC4J固有のアノテーションとその属性を使用して指定できます。
@StatelessDeployment
の属性transactionTimeout
@StatefulDeployment
の属性transactionTimeout
これらの属性の詳細は、表A-1を参照してください。
例21-5に、@StatelessDeployment
アノテーションを使用してEJB 3.0ステートレス・セッションBeanでこれらの属性を構成する方法を示します。
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");
}
}
orion-ejb-jar.xml
ファイルで、<session-deployment>
要素のtransaction-timeout
属性を使用してセッションBeanのトランザクション・タイムアウトを設定します。
たとえば、グローバル・トランザクション・タイムアウトを180秒に設定する場合は、次のようにします。
<session-deployment ... transaction-timeout="180" ... </session-deployment>
この方法を使用してこのプロパティを変更する場合は、OC4Jを再起動して変更を適用する必要があります。
メッセージドリブン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でこの属性を構成する方法を示します。
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) {
...
}
}
orion-ejb-jar.xml
ファイルで、トランザクション・タイムアウトを設定します。この値の構成方法は、使用しているメッセージドリブン・プロバイダのタイプによって決まります。
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アダプタ・メッセージ・サービス・プロバイダを使用している場合は、<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つの接続しか保持されないようにできます。
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
}
}
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は、借方計上を正常に実行し、貸方操作で障害が発生した場合に、トランザクションにロールバックのマークを付けることができます。
詳細は、次を参照してください。
|
![]() Copyright © 2002, 2008 Oracle Corporation. All Rights Reserved. |
|