ヘッダーをスキップ
Oracle TimesTen In-Memory Database Java開発者ガイド
リリース11.2.1
B56049-01
  目次
目次
索引
索引

戻る
戻る
 
次へ
次へ
 

3 イベント管理のためのJMS/XLAの使用

TimesTen JMS/XLA API(JMS/XLA)を使用すると、ローカル・データ・ストア内の特定の表への変更についてTimesTenを監視し、これらの変更の通知をリアルタイムで受信できます。JMS/XLAの目的の1つは、トリガーの代替手段として、高性能かつ非同期の機能を提供することです。

また、『Oracle TimesTen In-Memory Database TimesTen to TimesTen開発者および管理者ガイド』で説明しているTimesTenのレプリケーション・ソリューションが要件を満たしていない場合は、JMS/XLAを使用してカスタム・データ・レプリケーション・ソリューションを構築することもできます。

JMS/XLAはSun Microsystems社のJava Message Service(JMS)インタフェースを実装しているため、JavaアプリケーションでTimesTenトランザクション・ログAPI(XLA)機能を使用できます。 JMSの情報およびリソースは、次のSun Microsystems社のURLから利用可能です。

http://java.sun.com/products/jms/docs.html

また、Sun Microsystems社の標準のJMS APIドキュメントは、Oracle TimesTen In-Memory Databaseとともに次の場所にインストールされます。

install_dir/3rdparty/jms1.1/doc/api/index.html

TimesTen JMS/XLAアプリケーションをチューニングしてパフォーマンスを向上させる方法については、「JMS/XLAアプリケーションのチューニング」を参照してください。

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

JMS/XLAの概念

Javaアプリケーションは、JMS/XLA APIを使用してTimesTenからイベント通知を受信できます。JMS/XLAは、JMSパブリッシュ・サブスクライブ・インタフェースを使用してXLA更新へのアクセスを提供します。

XLAへの接続を提供するJMS Sessionを確立して永続サブスクライバ(TopicSubscriber)を作成し、更新をサブスクライブします。このサブスクライバを使用してメッセージを同時に受信および処理したり、リスナー(MessageListener)を実装して非同期に更新を処理できます。

JMS/XLAは、ローカル・データ・ストアを監視するアプリケーション用に設計されています。 TimesTenおよび通知を受信するアプリケーションは、同じシステム上に存在している必要があります。


注意:

JMS/XLA APIでは、永続モードのXLAがサポートされています。 このモードでは、XLAによって更新レコードがトランザクション・ログ・バッファまたはトランザクション・ログ・ファイルから直接取得されるため、それらの更新レコードは読み取られるまで使用可能です。 また、永続モードのXLAを使用すると、複数のリーダーでトランザクション・ログの更新に同時にアクセスできます。

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

XLAでレコードをトランザクション・ログから読み取る方法

アプリケーションによってTimesTenデータ・ストアが変更されると、TimesTenは、データに対して行われた変更およびトランザクション・コミットなど、その他のイベントを記述するトランザクション・ログ・レコードを生成します。

生成される新しいトランザクション・ログ・レコードは、常にトランザクション・ログ・バッファの最後に書き込まれます。 トランザクション・ログ・レコードは、メモリ内のログ・バッファからディスク上のトランザクション・ログ・ファイルへ定期的に一括でフラッシュされます。

アプリケーションで、XLAを使用し、TimesTenデータ・ストアへの変更に関してトランザクション・ログを監視できます。XLAは、トランザクション・ログ全体を読み取り、ログ・レコードをフィルタ処理し、目的の表および列への変更が含まれているトランザクション・レコードのリストをXLAアプリケーションに配信します。

XLAは、レコードをディスクリート・トランザクションにソートします。 複数のアプリケーションが同時にデータ・ストアを更新している場合、異なるアプリケーションのトランザクション・ログ・レコードがトランザクション・ログに交互に配置されます。

XLAは、特定のトランザクションに関連するすべてのトランザクション・ログ・レコードを透過的に抽出し、それらを連続するリストにしてアプリケーションに配信します。

コミット済のトランザクションのレコードのみが返されます。コミット済のレコードは、最後のコミット・レコードがトランザクション・ログに書き込まれる順序で返されます。コミットされていないデータ・ストアへの変更に関連するレコードは、XLAによってフィルタ処理されます。

変更が行われ、その後にロールバックされた場合、強制終了されたトランザクションのレコードはアプリケーションに配信されません。

これらのXLAの基本概念のほぼすべてを例3-1に示し、続いてそれぞれの内容を箇条書きで示します。

図3-1に示すトランザクション・ログを例として考えてみます。

図3-1 トランザクション・ログから抽出されるレコード

図3-1の説明が続きます。
「図3-1 トランザクション・ログから抽出したレコード」の説明

例3-1 トランザクション・ログ・レコードの読取り

この例では、トランザクション・ログに次のレコードが含まれています。


CT1 - アプリケーションCは、表Wの行1を値7.7で更新
BT1 - アプリケーションBは、表Xの行3を値2で更新
CT2 - アプリケーションCは、表Wの行9を値5.6で更新
BT2 - アプリケーションBは、表Yの行2を値XYZで更新
AT1 - アプリケーションAは、表Zの行1を値3で更新
AT2 - アプリケーションAは、表Zの行3を値4で更新
BT3 - アプリケーションBがトランザクションをコミット
AT3 - アプリケーションAがトランザクションをロールバック
CT3 - アプリケーションCがトランザクションをコミット

表W、YおよびZへの変更を検出するように設定されているXLAアプリケーションでは次のようになります。


BT2およびBT3 - 表Yの行2を値XYZで更新し、コミット
CT1 - 表Wの行1を値7.7で更新
CT2およびCT3 - 表Wの行9を値5.6で更新し、コミット

この例は、次のことを示します。

  • アプリケーションBおよびアプリケーションCのトランザクション・レコードがすべて同時に書き込まれます。

  • トランザクション・ログでは、アプリケーションCのレコードがアプリケーションBのレコードより前に書き込まれますが、アプリケーションBのコミット(BT3)はアプリケーションCのコミット(CT3)より前に書き込まれます。 その結果、アプリケーションBのレコードはアプリケーションCのレコードより先にXLAアプリケーションに返されます。

  • XLAは表Xへの変更を検出するように設定されていないため、アプリケーションBによる表Xへの更新(BT1)は示されません。

  • アプリケーションAによる表Zへの更新(AT1およびAT2)は示されません。コミットされずにロールバックされたためです(AT3)。

XLAおよびマテリアライズド・ビュー

XLAを使用すると、表およびマテリアライズド・ビューの両方への変更を追跡できます。 マテリアライズド・ビューによって、複数のディテール表内の選択した行および列への変更を追跡できる単一のソースが提供されます。マテリアライズド・ビューがない場合は、XLAアプリケーションで、すべてのディテール表の更新レコード(アプリケーションにとって重要ではない行および列への更新が反映されているレコードを含む)に対して監視およびフィルタ処理を行う必要があります。

通常、表に対する変更を追跡するためのXLAメカニズムと、マテリアライズド・ビューに対する変更を追跡するXLAメカニズムとの間に、処理上の違いはありません。 ただし、非同期マテリアライズド・ビューの場合、非同期ビューに関するXLA通知の順序が、関連付けられているディテール表に関する順序、または同期ビューに関する順序と同じとはかぎらないことに注意してください。 たとえば、ディテール表に対する挿入が2つある場合、非同期マテリアライズド・ビューでは、これらの2つが逆の順序で実行される可能性があります。 また、更新が、削除してから挿入として処理されたり、複数の挿入や複数の削除など、複数の処理が組み合される可能性があります。 処理の順序を保持する必要があるアプリケーションでは、非同期マテリアライズド・ビューを使用しないでください。

XLAブックマーク

XLAブックマークは、トランザクション・ログ内のXLAサブスクライバ・アプリケーションの読取り位置にマークを付けます。ブックマークによって永続サブスクリプションが容易になり、アプリケーションはトピックから切断した後、読取りを中断した時点から、更新の受信を継続するために再接続できます。

ブックマークの使用方法

XLAのメッセージ・コンシューマを作成する場合は、永続TopicSubscriberを使用します。サブスクライバを作成するときに指定するサブスクリプション識別子は、XLAブックマーク名として使用されます。 表に対するXLAパブリッシングを開始および停止するためにJDBCを介してttXlaSubscribeおよびttXlaUnsubscribe組込みプロシージャを使用する場合は、使用するブックマークの名前を明示的に指定します。

応答を受信すると、ブックマークは最終読取り位置にリセットされます。 更新メッセージが確認される方法の詳細は、「XLA応答モード」を参照してください。

JMS Sessionオブジェクトでunsubscribe()をコールすることによって、永続サブスクリプションを削除できます。これにより、対応するXLAブックマークが削除され、再接続するときに新規のサブスクリプションが強制的に作成されます。 詳細は、「ブックマークの削除」を参照してください。

使用中は、ブックマーク・サブスクリプションの変更はできません。 サブスクリプションの変更には、メッセージ・コンシューマをクローズしてから、ttXlaSubscribeおよびttXlaUnsubscribeを使用してサブスクリプションを変更して、その後メッセージ・コンシューマをオープンする必要があります。


注意:

ttXlaBookmarkCreate TimesTen組込みファンクションを使用して、ブックマークを作成することもできます。 このファンクションの詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のttXlaBookmarkCreateに関する項を参照してください。

レプリケートされるブックマーク

アクティブ・スタンバイ・ペア・レプリケーション・スキームを使用している場合、jmsxla.xmlファイル(「XLA構成ファイルおよびXLAトピック」を参照)内の<topic>要素のreplicatedBookmark属性に基づいたレプリケートされるブックマークを使用することができます。 レプリケートされるブックマークでは、ブックマークへの操作が必要に応じてスタンバイ・データベースにレプリケートされるため、スタンバイに対する必要な書き込み権限があることを想定しています。 これにより、フェイルオーバーのイベントにあるブックマークを、より効率的にリカバリできます。

アクティブ・データベースにあるレプリケートされるブックマークのみ、読み取りまたは応答が可能です。 レプリケートされるブックマークに応答するたびに、その応答操作がスタンバイ・データベースに非同期にレプリケートされます。


注意:

また、ttXlaBookmarkCreateを使用してブックマークを作成する場合、このファンクションで、レプリケートされるブックマークを指定する設定ができます。

次の点に注意してください。

  • スタンバイ・データベースのブックマークとアクティブ・データベースのブックマークは非常に近い位置にあります。ただし、応答操作のレプリケーションは非同期であるため、応答操作が実行される頻度によっては、フェイルオーバーのイベント中、重複する更新が小さなウィンドウに表示されることがあります。

  • アクティブ・スタンバイ・ペア・スキームを有効にしたときに、レプリケートされるブックマークがすでに存在している場合、ブックマークは自動的にレプリケーション・スキームに追加されます。

  • レプリケートされるブックマークが存在していても、アクティブ・スタンバイ・ペア・スキームは削除できます。 ブックマークは、その時点でレプリケートされなくなります。

  • レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。

JMS/XLA構成ファイルおよびXLAトピック

XLAに接続するには、特定のデータ・ストアに対応するJMSTopicへの接続を確立します。JMS/XLA構成ファイルでは、トピック名とデータ・ストア間のマッピングが提供されます。

トピックを指定する際、<topic>要素にreplicatedBookmark="yes"と設定すると、レプリケートされるブックマークを指定できます。 デフォルトの設定は"no"です。 「XLAブックマーク」を参照してください。

デフォルトでは、JMS/XLAは、現在の作業ディレクトリでjmsxla.xmlという構成ファイルを検索します。 そのファイルに別の名前または場所を使用する場合は、InitialContextクラスに環境変数の一部として指定し、その場所をCLASSPATHに追加する必要があります。

例3-2 JMS/XLA構成ファイルの指定

次のコードは、構成ファイルをInitialContextクラスの環境変数の一部として指定します。例3-2のようなコードを使用します。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
  "com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");
env.put(XlaConstants.CONFIG_FILE_NAME, "/newlocation.xml");
InitialContext ic = new InitialContext(env);

XlaConstants.CONFIG_FILE_NAMEが設定されている場合、JMS/XLA APIでは、クラス・ローダーを使用してJMS/XLA構成ファイルを検索します。 例3-2では、JMS/XLA APIは、CLASSPATH環境変数で指定されている場所と、CLASSPATH環境変数で指定されているJARファイル内の最上位のディレクトリにあるnewlocation.xmlファイルを検索します。

また、JMS/XLA構成ファイルは、次のようにサブディレクトリに配置することもできます。

env.put(XlaConstants.CONFIG_FILE_NAME,
"/com/mycompany/myapplication/deepinside.xml");

この場合、JMS/XLA APIは、CLASSPATH環境変数で指定されている場所およびCLASSPATH環境変数で指定されているjarファイル内の両方のcom/mycompany/myapplicationサブディレクトリで、deepinside.xmlファイルを検索します。

JMS/XLA APIでは、最初に見つかった構成ファイルを使用します。

例3-3 構成ファイル内のトピックの定義

構成ファイル内のトピック定義は、名前、JDBC接続文字列、および1回で取得する更新数を指定するプリフェッチ値で構成されています。

たとえば、ここに示す構成ファイルでは、DemoDataStoreトピックがTestDB DSNにマップされています。

<xlaconfig>
  <topics>
    <topic name="DemoDataStore"
      connectionString="jdbc:timesten:direct:DSN=TestDB"
      xlaPrefetch="100"
  />
  </topics>
</xlaconfig>

例3-4 レプリケートされるブックマークを使用するトピックの定義

レプリケートされるブックマークを使用するかどうかを、トピック定義で指定することもできます。 レプリケートされるブックマークを前述の例に使用すると次のようになります。

<xlaconfig>
  <topics>
    <topic name="DemoDataStore"
      connectionString="jdbc:timesten:direct:DSN=TestDB"
      xlaPrefetch="100" replicatedBookmark="yes"
  />
  </topics>
</xlaconfig>

XLA更新

アプリケーションは、JMS MapMessageオブジェクトとしてXLA更新を受け取ります。 MapMessageには、XLA更新ヘッダー内のフィールドに対応する一連の名前/値ペアが含まれています。

MapMessage取得メソッドを使用してメッセージ・フィールドにアクセスできます。 getMapNames()メソッドは、メッセージ内のすべてのフィールドの名前を含むEnumerationオブジェクトを返します。メッセージの個々のフィールドを名前ごとに取得できます。予約されたすべてのフィールド名は、__TYPEのように2つのアンダースコアで始まります。

すべての更新メッセージには、メッセージに含まれている更新のタイプを示す__TYPEフィールドがあります。タイプは、整数値で指定されています。整数タイプと比較するために、com.timesten.dataserver.jmsxla.XlaConstantsに定義されている定数を使用します。 表3-1に、サポートされているタイプを示します。

表3-1 XLA更新タイプ

更新タイプ 説明

INSERT

行が追加されました。

UPDATE

行が変更されました。

DELETE

行が削除されました。

COMMIT_ONLY

トランザクションがコミットされました。

CREATE_TABLE

表が作成されました。

DROP_TABLE

表が削除されました。

CREATE_INDEX

索引が作成されました。

DROP_INDEX

索引が削除されました。

ADD_COLUMNS

新規の列が表に追加されました。

DROP_COLUMNS

列が表から削除されました。

CREATE_VIEW

マテリアライズド・ビューが作成されました。

DROP_VIEW

マテリアライズド・ビューが削除されました。

CREATE_SEQ

SEQUENCEが作成されました。

DROP_SEQ

SEQUENCEが削除されました。

TRUNCATE

表が切り捨てられ、表内のすべての行が削除されました。


XLA更新メッセージの内容の詳細は、「JMS/XLA MapMessageの内容」を参照してください。

XLA応答モード

XLAの応答メカニズムは、アプリケーションがメッセージを受信するだけでなく、メッセージを正常に処理できるように設計されています。 永続的に更新に応答すると、アプリケーションのXLAブックマークは、読み取られた最終レコードにリセットされます。 これにより、以前に返されたレコードが再度読み取られることを回避できます。また、アプリケーションがXLAに再接続したときにブックマークが再利用された場合、以前に応答されたレコードをアプリケーションが受信しないようにすることもできます。

JMS/XLAは、XLA更新メッセージに自動的に応答することも、応答するメッセージを明示的に選択することもできます。 Sessionオブジェクトを作成したときに、更新の応答方法を指定します。

JMS/XLAでは、次の3つの応答方法がサポートされています。

  • AUTO_ACKNOWLEDGE: このモードでは、更新を受信したときに自動的にその更新が確認されます。 各メッセージは1回のみ配信されます。 重複するメッセージは送信されないため、アプリケーションに障害が発生すると、メッセージが消失することがあります。AUTO_ACKNOWLEDGEモードでは、メッセージは必ず個々に配信されて確認されるため、JMS/XLAは複数のレコードをプリフェッチしません トピック内のxlaprefetch属性は無視されます。

  • DUPS_OK_ACKNOWLEDGE: このモードでは、更新は自動的に応答されますが、アプリケーションに障害が発生すると、重複するメッセージが配信されることがあります。 DUPS_OK_ACKNOWLEDGEモードでは、JMS/XLAはトピックに対して指定されているxlaprefetch属性に基づいてレコードをプリフェッチし、プリフェッチされたブロック内の最終レコードが読み取られると応答を送信します。プリフェッチされたすべてのレコードを読み取る前にアプリケーションに障害が発生すると、ブロック内のすべてのレコードは、アプリケーションの再起動時にアプリケーションに渡されます。

  • CLIENT_ACKNOWLEDGE: このモードでは、アプリケーションはMapMessageへのacknowledge()をコールすることによって更新メッセージの受信を確認します。CLIENT_ACKNOWLEDGEモードでは、JMS/XLAはトピックに指定されているxlaprefetch属性に基づいてレコードをプリフェッチします。

更新のプリフェッチ

複数の更新レコードを一度にプリフェッチする処理は、XLAから各更新レコードを個々に取得する処理より効率的です。AUTO_ACKNOWLEDGEモードを使用すると、更新がプリフェッチされないため、他のモードよりも時間がかかります。可能な場合は、更新を重複して行うことができるようにアプリケーションを設計してください。これによって、DUPS_OK_ACKNOWLEDGEの使用、または更新の明示的な確認が可能になります。各メッセージに対して個々に応答しないようにすると、通常は明示的な更新の応答によって、最も高いパフォーマンスを得ることができます。

更新の確認

XLA更新に明示的に応答するには、更新メッセージでacknowledge()をコールします。メッセージに暗黙的に応答すると、以前のすべてのメッセージに応答されます。 通常は、応答と応答の間に、複数の更新メッセージを受信および処理します。 CLIENT_ACKNOWLEDGEモードを使用していて、永続サブスクリプションを将来再利用する場合は、終了する前に、acknowledge()をコールして最後に読み取られた位置にブックマークを再設定する必要があります。

アクセス制御がXLAに与える影響

「アクセス制御のためのTimesTen機能の検討」では、TimesTenアクセス制御がデータベースの操作に与える影響の概要を提供しています。 アクセス制御は、XLAに次のような影響を与えます。

  • XLA機能を実行するには、システム権限XLAが必要です。 これには、TimesTenにXLAリーダーとして接続して、ttXlaBookmarkCreatettXlaBookmarkDeletettXlaSubsribeおよびttXlaUnsubscribe TimesTen XLA組込みファンクション(『Oracle TimesTen In-Memory Databaseリファレンス』の組込みプロシージャに関する項を参照してください)を実行することも含まれます。

  • XLA権限を持つユーザーは、SELECT ANY TABLEおよびSELECT ANY SEQUENCEのシステム権限と同等の操作を実行できます。

JMS/XLAとOracle GDKの依存性

JMS/XLA APIでは、DatabaseCharacterSet属性で指定されているデータベース・キャラクタ・セットからUTF-16エンコーディングに変換するために、Oracle Globalization Development Kit(GDK)の一部であるorai18n.jarを使用します。 JMS/XLA APIは、TimesTenのリリースごとに固有のバージョンのGDKをサポートしています。 JMS/XLAによって、JVMにすでにロードされている以外のバージョンのGDKが検出されると、重大な警告が表示され、処理が続行されます。 次のコマンドを入力すると、JMS/XLAでサポートされているGDKのバージョンを確認できます。

$ cd install_dir/lib
$ java -cp ./orai18n.jar oracle.i18n.util.GDKOracleMetaData -version

XLAへの接続

更新を受信するためにXLAに接続するには、JMS ConnectionFactoryを使用してConnectionを作成します。 次に、Connectionを使用してSessionを確立します。 更新の処理を開始する準備ができたら、Connectionstartをコールしてメッセージの配信を有効にします。 例3-5を参照してください。

例3-5 XLAへの接続

ConnectionFactory connectionFactory;

Context messaging = new InitialContext();
connectionFactory = (ConnectionFactory) messaging.lookup("ConnectionFactory");
Connection connection = connectionFactory.createConnection();

Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);

connection.start();

表への更新の監視

更新の受信を開始する前に、変更の監視対象となる表をXLAに指定する必要があります。

変更をサブスクライブして、表に対するXLAパブリッシングをオンにするには、JDBCを介してttXlaSubscribe組込みプロシージャをコールします。

ttXlaSubscribeを使用して表に対するXLAパブリッシングを有効にする場合は、次のように表を追跡するときに使用される2つのパラメータ(表の名前とブックマークの名前)を指定する必要があります。

ttXlaSubscribe(user.table, mybookmark)

たとえば、次のようにして、JDBC CallableStatementインタフェースでttXlaSubscribeをコールします。

Connection con;

CallableStatement cStmt;
...
cStmt = con.prepareCall("{call ttXlaSubscribe(user.table, mybookmark)}");
cStmt.execute();

停止時に、表からのサブスクライブを解除するには、ttXlaUnsubscribeを使用します。 詳細は、「表からのサブスクライブ解除」を参照してください。

SYS.XLASUBSCRIPTIONSシステム表を確認することで、アプリケーションで表のサブスクリプションを検証できます。

JavaアプリケーションでTimesTen組込みプロシージャを使用する場合の詳細は、「TimesTen組込みプロシージャのコール」を参照してください。

更新の受信および処理

XLA更新は、同期または非同期に受信できます。

トピックの更新を同期をとって受信および処理するには、次の手順を実行します。

  1. 永続TopicSubscriberインスタンスを作成してトピックをサブスクライブします。

  2. サブスクライバでreceive()またはreceiveNoWait()をコールして、次に使用可能な更新を取得します。

  3. 返されたMapMessageインスタンスを処理します。

トピックの更新を非同期に受信および処理するには、次の手順を実行します。

  1. 更新を処理するMessageListenerインスタンスを作成します。

  2. トピックをサブスクライブする、永続TopicSubscriberインスタンスを作成します。

  3. TopicSubscriberMessageListenerを登録します。

  4. 接続を開始します。


    注意:

    接続を開始する前にMessageListenerを登録する必要があります。これを行わないと、メッセージが表示されない可能性があります。 接続済の場合は、接続を停止してMessageListenerを登録した後に、接続を再開します。

  5. メッセージを受信するまで待機します。 アプリケーションがメイン・スレッド内で行う処理が他にない場合は、Objectメソッドwait()をコールしてメッセージを待機できます。

更新がパブリッシュされると、MessageListenerメソッドonMessage()がコールされ、メッセージがMapMessageインスタンスとして渡されます。

SYS.XLASUBSCRIPTIONSシステム表を確認することで、アプリケーションで表のサブスクリプションを検証できます。

例3-6では、リスナーを使用して更新を非同期に処理します。

例3-6 リスナーを使用した更新の非同期処理

MyListener myListener = new MyListener(outStream);

outStream.println("Creating consumer for topic " + topic);
Topic xlaTopic = session.createTopic(topic);
TopicSubscriber subscriber =
    session.createDurableSubscriber(xlaTopic, "mybookmark");

subscriber.setMessageListener(myListener);

mybookmarkがすでに存在している必要があります。 JDBCおよびttXlaBookmarkCreate組込みプロシージャを使用して、ブックマークを作成できます。また、TopicSubscriberは、永続サブスクライバである必要があります。XLA接続は永続的であるように設計されています。XLAブックマークによって、トピックからの切断が可能になり、更新が中断した位置から更新の受信を開始するために、再度接続することもできます。永続サブスクライバの作成時にサブスクリプション識別子として渡すStringは、XLAブックマーク名として使用されます。

JMS TopicSessionunsubscribe()をコールして、アプリケーションの停止時にそのサブスクライバが使用したXLAブックマークを削除できます。これによって、アプリケーションの再起動時に、新しいブックマークが作成されます。

更新を受信すると、MapMessage取得メソッドを使用してメッセージから情報を抽出し、アプリケーションで必要な処理を行うことができます。 TimesTen XlaConstantsクラスでは、XLA更新メッセージの処理を簡単にするために、更新タイプおよび特別なメッセージ・フィールドの定数が定義されています。

通常、メッセージに含める更新タイプを最初に決定します。 MapMessageメソッドgetInt()を使用して__TYPEフィールドの内容を取得し、the XlaConstantsクラスで定義されている数値定数とその値を比較します。

例3-7では、onMessageメソッドはMapMessageオブジェクトから更新タイプを抽出し、更新が示している処理を表示します。

例3-7 更新タイプの決定

public void onMessage(Message message) {
  MapMessage mapMessage = (MapMessage) message;
  String messageType = null;
  if (message == null) {
    errStream.println("MyListener: update message is null");
    return;
  }

  try {
    // Get the update type(insert, update, delete, etc.).
    int type = mapMessage.getInt(XlaConstants.TYPE_FIELD);
    if (type == XlaConstants.INSERT) {
      System.out.println("A row was inserted.");
    } else if (type == XlaConstants.UPDATE) {
      System.out.println("A row was updated.");
    } else if (type == XlaConstants.DELETE) {
      System.out.println("A row was deleted.");
    } else {
      return;
    }

受信したメッセージのタイプがわかれば、アプリケーションにおける必要性に応じて、メッセージを処理できます。 メッセージのすべてのフィールドのリストを取得するには、MapMessageメソッドgetMapNames()をコールします。メッセージの個々のフィールドを名前ごとに取得できます。

例3-8は、列名を使用して、挿入、更新および削除メッセージから列値を抽出します。

例3-8 列値の抽出

if (type == XlaConstants.INSERT
  || type == XlaConstants.UPDATE
  || type == XlaConstants.DELETE) {
    // Get the column values from the message.
    int cust_num = mapMessage.getInt("cust_num");
    String region = mapMessage.getString("region");
    String name = mapMessage.getString("name");
    String address = mapMessage.getString("address");

    System.out.println("New Column Values:");
    System.out.println("cust_num=" + cust_num);
    System.out.println("region=" + region);
    System.out.println("name=" + name);
    System.out.println("address=" + address);
  }

XLA更新メッセージの内容の詳細は、「JMS/XLA MapMessageの内容」を参照してください。 また、TimesTenの列の型がどのようにJMSデータ型にマップされているか、および列値を取得するために使用する取得メソッドについては、「データ型のサポート」を参照してください。

JMS/XLAアプリケーションの終了

XLAアプリケーションがトランザクション・ログからの読取りを終了した場合は、XLA接続をクローズして不要なブックマークを削除し、明示的にサブスクライブした表をサブスクライブ解除して、正常に終了する必要があります。

接続のクローズ

XLAへの接続をクローズするには、Connectionオブジェクトでclose()をコールします。

接続がクローズされた後、その接続、セッションまたはサブスクライバを使用しようとすると、 IllegalStateExceptionがスローされます。 その接続から受信したメッセージを継続して使用できますが、接続がクローズされた後、受信したメッセージのacknowledge()メソッドをコールすることはできません。

ブックマークの削除

停止時にXLAブックマークを削除するかどうかは、任意に選択できます。ブックマークを削除すると、トランザクション・ログ内の未読の更新レコードに関連するディスク領域を解放できます。

ブックマークを削除しない場合は、永続サブスクライバで再利用できます。永続サブスクライバが再接続するときにブックマークが使用可能な場合、サブスクライバは、以前の接続が終了した後に発行されたすべての未確認の更新を受信します。ブックマークが存在しており、そのブックマークから読取りを行っているアプリケーションがない場合は、トランザクション・ログのサイズが継続して大きくなり、データベースによって消費されるディスク領域が増加します。

ブックマークを削除するには、JMS Sessionでunsubscribeをコールします。これにより、ttXlaBookmarkDelete組込みプロシージャが起動され、XLAブックマークが削除されます。


注意:

レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。

表からのサブスクライブ解除

表に対するXLAパブリッシングをオフにするには、ttXlaUnsubscribe組込みプロシージャを使用します。 ttXlaSubscribeを使用して表に対するXLAパブリッシングを有効にする場合は、アプリケーションを停止するときにttXlaUnsubscribeを使用して表からのサブスクライブ解除を行う必要があります。


注意:

表を削除する場合は、まず表からサブスクライブ解除します。

表からのサブスクライブ解除を行う場合は、次のように表を追跡するときに使用される表の名前とブックマークの名前を指定します。

ttXlaUnsubscribe(user.table, mybookmark)

たとえば、CallableStatementオブジェクトでttXlaUnSubscribeをコールするには、次の例のようにします。

例3-9 表からのサブスクライブ解除

Connection con;

CallableStatement cStmt;
...
cStmt = con.prepareCall("{call ttXlaUnSubscribe(user.table, mybookmark)}");
cStmt.execute();

JavaアプリケーションでTimesTen組込みプロシージャを使用する場合の詳細は、「TimesTen組込みプロシージャのコール」を参照してください。

レプリケーション・メカニズムとしてのJMS/XLAの使用

『Oracle TimesTen In-Memory Database TimesTen to TimesTen開発者および管理者ガイド』で説明するTimesTenのレプリケーション・ソリューションが要件を満たしていない場合は、JMS/XLAを使用してソース・データ・ストアからターゲット・データ・ストアに更新をレプリケートできます。

ターゲット・データ・ストアへのJMS/XLAメッセージの適用

ソース・データ・ストアによってJMS/XLAメッセージが生成されます。メッセージをターゲット・データ・ストアに適用するには、メッセージからXLA記述子を抽出する必要があります。 MapMessageインタフェースを使用して更新記述子を抽出します。

MapMessage message;
/**
 *...other code
 */
try {
  byte[]updateMessage=
    mapMessage.getBytes(XlaConstants.UPDATE_DESCRIPTOR_FIELD);
}
catch (JMSException jex){
/**
 *...other code
 */
}

ターゲット・データ・ストアがソース・データ・ストアとは異なるシステムに存在する場合があります。更新記述子はバイト配列として返され、ネットワーク送信のためにシリアライズすることができます。

ソース・データ・ストアからのオブジェクトを適用するために、ターゲット・データ・ストアを表すターゲット・データ・ストア・オブジェクトを作成する必要があります。 TargetDataStoreImplクラスのインスタンスとしてmyTargetDataStoreというターゲット・データ・ストア・オブジェクトを作成できます。次に例を示します。

TargetDataStore myTargetDataStore=
   new TargetDataStoreImpl("DSN=sampleDSN");

TargetDataStoreメソッドapply()を使用して、myTargetDataStoreにメッセージを適用します。次に例を示します。

myTargetDataStore.apply(updateDescriptor);

デフォルトでは、TimesTenは、更新を適用する前にターゲット・データ・ストア上の競合を確認します。 ターゲット・データ・ストアに更新時よりも新しい情報がある場合は、TargetDataStoreによって例外がスローされます。 TimesTenで競合を確認しない場合は、TargetDataStoreメソッドsetUpdateConflictCheckFlag()を使用して動作を変更します。

デフォルトでは、TimesTenは、更新記述子に含まれているコミット・フラグとトランザクション境界に基づいてデータ・ストアに対する更新をコミットします。 アプリケーションで手動コミットを実行する場合は、setAutoCommitFlag()メソッドを使用して自動コミット・フラグを変更します。 myTargetDataStoreに対して手動コミットを実行するには、次のコマンドを使用します。

myTargetDataStore.commit();

更新アプリケーションでエラーが発生した場合は、ロールバックを実行できます。 myTargetDataStoreに対して次のコマンドを使用します。

myTargetDataStore.rollback();

次のコマンドを使用して、myTargetDataStoreをクローズします。

myTargetDataStore.close;

TargetDataStoreインタフェースの詳細は、「JMS/XLAレプリケーションAPI」を参照してください。

TargetDataStoreのエラー・リカバリ

TargetDataStoreを起動すると、一時的なエラーと永続的なエラーが発生する可能性があります。

一時的なエラーが発生すると、TargetDataStoreメソッドによって0(ゼロ)以外の値が返されます。 アプリケーションは処理を再試行することができ、再適用する必要がある更新記述子を監視します。 一時的なXLAのエラーの詳細は、『Oracle TimesTen In-Memory Database C開発者ガイド』のXLAのエラーの処理に関する項を参照してください。

永続的なエラーに対しては、TargetDataStoreメソッドによってJMSExceptionオブジェクトが返されます。アプリケーションが永続的なエラーを受信すると、データ・ストアが有効かどうかを確認する必要があります。データ・ストアが無効な場合は、ターゲット・データ・ストア・オブジェクトをクローズし、新しいオブジェクトを作成する必要があります。その他のタイプの永続的なエラーには、手動での操作が必要になる場合があります。

次の例に、TargetDataStoreオブジェクトからエラーをリカバリする方法を示します。

例3-10 エラーのリカバリ

TargetDataStore theTargetDataStore;
byte[] updateDescriptor;
int rc;

// Other code
try {
  ...
  if ( (rc = theTargetDataStore.apply(updateDescriptor) ) == 0 ) {
    // apply successful
  }
  else {
    // Transient error. Retry later.
  }
 }
catch (JMSException jex) {
  if (theTargetDataStore.isDataStoreValid() ) {
    // Data store is valid; permanent error that may need Administrator intervention.
  }
  else {
    try {
      theTargetDataStore.close();
  }
  catch (JMSException closeEx) {
    // Close errors are not usual. This may need Administrator intervention.
  }
}