注意:
この項で説明するJMSクラスの詳細は、Java Webサイト(http://www.oracle.com/technetwork/java/jms/index.html
)にある最新のJMS仕様とJavadocを参照してください。
トランザクションを使用すると、アプリケーションでは生成および消費されるメッセージのグループを調整し、送受信する複数のメッセージを基本単位として処理できます。
アプリケーションがトランザクションをコミットすると、トランザクション内で受信した全メッセージはメッセージング・システムから削除され、トランザクション内で送信したメッセージが実際に配信されます。アプリケーションによってトランザクションがロールバックされた場合、トランザクション内で受信したメッセージはメッセージング・システムに戻され、送信したメッセージは破棄されます。
トピック・サブスクライバによってロールバックされた受信メッセージはサブスクライバに再配信されます。キュー・レシーバによってロールバックされた受信メッセージは、コンシューマではなくキューに再配信されます。それによって、キュー内の他のコンシューマがメッセージを受信できるようにします。
たとえばオンライン・ショッピングでは、品物を選択し、それをオンライン・ショッピング・カートに入れます。注文した品物はトランザクションの一部として格納されますが、チェックアウトして注文を確定するまでユーザーの支払い義務は発生しません。ユーザーはいつでも注文を取り消し、カートを空にすることができます。取消によって、現在のトランザクション内で注文がロールバックされます。
JMSでトランザクションを使用する方法には以下の3種類があります。
トランザクションでJMSのみを使用する場合は、JMSトランザクション・セッションを作成できます。
EJBなどの他の処理とJMSを混在させる場合は、JMS非トランザクション・セッションでJava Transaction API (JTA)ユーザー・トランザクションを使用します。
メッセージドリブンBeanを使用します。
以降の節では、JMSトランザクション・セッションとJTAユーザー・トランザクションの使い方について説明します。
注意:
トランザクションを使用する場合、トランザクションがコミットまたはロールバックされる前に発生する問題に対処するために、「セッション例外リスナーの定義」で説明しているようにセッション例外リスナーを定義しておくことをお薦めします
acknowledge()
メソッドは、トランザクション内で呼び出されても無視されます。recover()メソッドがトランザクション内で呼び出されると、JMSException
がスローされます。
JMSトランザクション・セッションは、セッション内にあるトランザクションをサポートします。JMSトランザクション・セッションのトランザクションはセッション外には影響を及ぼしません。たとえば、セッションをロールバックしても、そのセッションの送受信がロールバックされるだけで、データベース更新はロールバックされません。JTAユーザー・トランザクションはJMSトランザクション・セッションでは無視されます。
JMSトランザクション・セッションのトランザクションは、最初の送受信処理が発生した後で暗黙的に開始され、互いに結び付けられます。トランザクションをコミットまたはロールバックすると、他のトランザクションが自動的に始まります。
システム管理者は、JMSトランザクション・セッションを使用する前に、アプリケーション開発環境の必要性に応じて、接続ファクトリの属性(トランザクション・タイムアウト)とセッション・プールの属性(トランザクション)を調整する必要があります。
JMSトランザクション・セッションの設定および使用に必要な手順を次の図に示します。
「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定しますが、「ステップ3: 接続を使用してセッションを作成する」でセッションを作成する際に、ブール値transacted
をtrue
に設定してセッションをトランザクション処理されるように指定します。
たとえば、PTPおよびPub/Subメッセージング・モデルのトランザクション・セッションを作成する方法を次の各メソッドで示します。
qsession = qcon.createQueueSession( true, Session.AUTO_ACKNOWLEDGE ); tsession = tcon.createTopicSession( true, Session.AUTO_ACKNOWLEDGE );
定義したら、次のセッション・メソッドでセッションをトランザクション処理するかどうかを決定できます。
public boolean getTransacted( ) throws JMSException
注意:
acknowledge値はトランザクション・セッションでは無視されます。
必要な処理を実行したら、以下のメソッドのいずれかを実行してトランザクションをコミットまたはロールバックします。
トランザクションをコミットするには、次のメソッドを実行します。
public void commit( ) throws JMSException
commit()
メソッドでは、現在のトランザクションの送受信メッセージがすべてコミットされます。受信メッセージはメッセージング・システムから削除されますが、送信メッセージは表示されるようになります。
トランザクションをロールバックするには、次のメソッドを実行します。
public void rollback( ) throws JMSException
rollback()
メソッドでは、現在のトランザクションの送信メッセージが取り消され、受信メッセージがメッセージング・システムに戻されます。
commit()
メソッドまたはrollback()
メソッドがJMSトランザクション・セッション以外で発行された場合、IllegalStateException
がスローされます。
Java Transaction API (JTA)は、複数のデータ・リソースにわたるトランザクションをサポートします。JTAはWebLogic Serverの一部として実装され、トランザクション管理を実装するための標準Javaインタフェースを提供します。
トランザクションを開始、コミット、ロールバックするためのjavax.transaction.UserTransaction
オブジェクト(http://www.oracle.com/technetwork/java/javaee/jta/index.html
)を使用してJTAユーザー・トランザクション・アプリケーションをプログラミングします。JTAユーザー・トランザクション内にJMSとEJBを混在させる場合、『Oracle WebLogic Server JTAアプリケーションの開発』のEJBアプリケーションのトランザクションに関する項で説明しているとおりにEJBからトランザクションを開始することもできます。
トランザクション・セッションの開始後にJTAユーザー・トランザクションを開始できます。ただし、JTAユーザー・トランザクションはトランザクション・セッションに無視され、トランザクション・セッションはJTAユーザー・トランザクションに無視されます。
WebLogic Serverは2フェーズ・コミット(2PC)プロトコルをサポートしています。2PCでは、複数のリソース・マネージャ間で1つのJTAトランザクションを効率的に調整できるようになります。これにより、トランザクションによる更新を関連するリソース・マネージャのすべてでコミットするか、またはすべてのリソース・マネージャから完全にロールバックし、トランザクション開始前の状態に戻すことで、データの整合性が保証されます。
システム管理者は、JTAトランザクション・セッションを使用する前に、「XA接続ファクトリを有効化」チェック・ボックスをオンにして、JTAユーザー・トランザクションをサポートするように接続ファクトリを構成する必要があります。
JTAユーザー・トランザクションの設定および使用に必要な手順を次の図に示します。
「JMSアプリケーションの設定」の説明に従ってJMSアプリケーションを設定しますが、「ステップ3: 接続を使用してセッションを作成する」でセッションを作成する際に、ブール値transacted
をfalse
に設定してセッションをトランザクション処理されないように指定します。
たとえば、PTPおよびPub/Subメッセージング・モデルの非トランザクション・セッションを作成する方法を次の各メソッドで示します。
qsession = qcon.createQueueSession( false, Session.AUTO_ACKNOWLEDGE ); tsession = tcon.createTopicSession( false, Session.AUTO_ACKNOWLEDGE );
注意:
ユーザー・トランザクションがアクティブな場合、確認応答モードは無視されます。
アプリケーションは、JNDIを使用して、WebLogic ServerドメインのUserTransaction
オブジェクトに対するオブジェクト参照を返します。
JNDIコンテキスト(context
)を確立して次のようなコードを実行すると、UserTransaction
オブジェクトをルックアップできます。
UserTransaction xact = ctx.lookup("javax.transaction.UserTransaction");
UserTransaction.begin()
メソッドを使用してJTAユーザー・トランザクションを開始します。例:
xact.begin();
必要な処理を実行したら、以下のcommit()
またはrollback()
メソッドをUserTransaction
オブジェクトで実行してJTAユーザー・トランザクションをコミットまたはロールバックします。
トランザクションをコミットするには、次のcommit()
メソッドを実行します。
xact.commit();
commit()
メソッドを実行すると、WebLogic Serverはトランザクション・マネージャを呼びだしてトランザクションを完了し、現在のトランザクションで実行されている全処理をコミットします。トランザクション・マネージャの役割は、リソース・マネージャと協力してデータベースを更新することです。
トランザクションをロールバックするには、次のrollback()
メソッドを実行します。
xact.rollback();
rollback()
メソッドを実行すると、WebLogic Serverはトランザクション・マネージャを呼び出してトランザクションを取り消し、現在のトランザクションで実行されている全処理をロールバックします。
commit()
またはrollback()
メソッドを呼び出したら、xact.begin()
を呼び出して別のトランザクションを開始することもできます。
JMSでは非同期的に配信されるメッセージでどのトランザクションを使用するかを決定できないため、JMS非同期メッセージ配信はJTAユーザー・トランザクションではサポートされません。
ただし、メッセージドリブンBeanによるかわりの方法が提供されます。メッセージドリブンBeanでは、メッセージ配信の直前にユーザー・トランザクションを自動的に開始できます。
メッセージドリブンBeanによる非同期メッセージ配信のシミュレートについては、『Oracle WebLogic Server Enterprise JavaBeansバージョン2.1の開発』のメッセージドリブンEJBの設計に関する項を参照してください。
以下の例では、JNDIを使用してjavax.transaction.UserTransaction
をルックアップすることにより、JTAユーザー・トランザクション内にEJBとJMSの処理が混在するようにアプリケーションを設定し、JTAユーザー・トランザクションを開始してからコミットする手順を示します。この例を実行するには、システム管理者が接続ファクトリを構成するときに、「XA接続ファクトリを有効化」チェック・ボックスをオンにする必要があります。
注意:
この単純なJTAユーザー・トランザクションの例に加えて、EXAMPLES_HOME
\wl_server\examples\src\examples\jta\jmsjdbc
ディレクトリにあるWebLogic JTA付属の例も参照してください。EXAMPLE_HOME
は、WebLogic Serverのサンプル・コードが構成されるディレクトリを表します。
javax.transaction.UserTransaction
パッケージ(http://www.oracle.com/technetwork/java/javaee/jta/index.html
)を含め、適切なパッケージをインポートします。
import java.io.*; import java.util.*; import javax.transaction.UserTransaction; import javax.naming.*; import javax.jms.*;
JTAユーザー・トランザクション変数などの必要な変数を定義します。
public final static String JTA_USER_XACT= "javax.transaction.UserTransaction"; . . .
非トランザクション・セッションを作成して、JMSアプリケーションを設定します。JMSアプリケーションの設定については、「JMSアプリケーションの設定」を参照してください
//JMS application setup steps including, for example: qsession = qcon.createQueueSession(false, Session.CLIENT_ACKNOWLEDGE);
JNDIでUserTransaction
をルックアップします。
UserTransaction xact = (UserTransaction) ctx.lookup(JTA_USER_XACT);
すべての参加ドメインについて、クロス・ドメイン・セキュリティまたはセキュリティの相互運用モードのいずれかを適切に構成する必要があります。
プロセスで使用されるすべてのドメインに関して、クロス・ドメイン・セキュリティおよびセキュリティの相互運用モードの構成を統一します。どちらの設定もドメイン・レベルで設定されるため、ドメインがクロス・ドメイン・セキュリティとセキュリティの相互運用モードの両方が設定された混在モードになる可能性があります。詳細は、『Oracle WebLogic Server JTAアプリケーションの開発』のドメイン間およびドメイン内トランザクションに対するセキュアな通信の構成に関する項を参照してください。