JMS/XLAの概念と機能

この項では、JMS/XLAの概念と機能の概要を示します。

また、JMSの情報およびリソースは次の場所から利用可能です。

http://www.oracle.com/technetwork/java/jms/index.html

また、標準のJMS APIドキュメントは、TimesTenとともに次の場所にインストールされています。

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

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

JMS/XLAの概念

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

TimesTen JMS/XLAサポートには、Jakarta Messaging APIバージョン1.1に基づくJMSプロバイダと、別のベースのJava Message Service APIバージョン1.1のJMSプロバイダの2つが含まれています。Jakarta Messaging APIバージョン1.1は、javax.jmsのかわりにネームスペースjakarta.jmsを使用する場合を除き、機能的にはJava Message Service APIバージョン1.1と同等です。

JMS/XLAはJMSインタフェースを実装しているため、JavaアプリケーションでTimesTenトランザクション・ログAPI (XLA)機能を使用できます。JMS/XLA APIはXLAのラッパーであり、これによって更新レコードがトランザクション・ログ・バッファまたはトランザクション・ログ・ファイルから直接取得されるため、それらの更新レコードは読み取られるまで使用可能です。XLAを使用すると、複数のリーダーでトランザクション・ログの更新に同時にアクセスできます。『Oracle TimesTen In-Memory Database C開発者ガイド』XLAおよびTimesTenイベント管理を参照してください。

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

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

ノート:

『Oracle TimesTen In-Memory Databaseレプリケーション・ガイド』TimesTenレプリケーションの概要で説明されているTimesTenレプリケーション・ソリューションでは必要に満たない場合は、JMS/XLAを使用してカスタム・データ・レプリケーション・ソリューションを構築することもできます。

どのようにXLAでトランザクション・ログからレコードが読み取られるか

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

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

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

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

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

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

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

図3-1に示すトランザクション・ログ、およびこれらのXLAのほとんどの概念を示す次の例を検討してください。

図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がトランザクションをコミット。

WYおよび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ブックマーク

この項では、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ファイル内の<topic>要素のreplicatedBookmark属性に従って、レプリケートされたブックマークを使用できます。

「JMS/XLA構成ファイルおよびトピック」を参照してください。

レプリケートされるブックマークでは、ブックマークへの操作が必要に応じてスタンバイ・データベースにレプリケートされるため、スタンバイに対する必要な書き込み権限があることを想定しています。これにより、フェイルオーバーが発生した場合、より効率的にブックマークの位置をリカバリできます。

レプリケートされたブックマークを使用する際には、次の順でステップを実行する必要があります。

  1. アクティブ・スタンバイ・ペアのレプリケーション・スキームを作成します。(これはcreate active standby pair操作、またはクラスタウェア管理環境のttCWAdmin -createコマンドによって行われます。)
  2. ブックマークを作成します。
  3. ブックマークをサブスクライブします。
  4. アクティブ・スタンバイ・ペアを起動します(このとき、スタンバイへの複製が発生し、レプリケーションが始まります)。(これはttRepAdmin -duplicateコマンド、またはクラスタウェア管理環境のttCWAdmin -startコマンドによって行われます。)

ノート:

  • あるいは、ttXlaBookmarkCreateを使用してブックマークを作成する場合、このファンクションには、レプリケートされるブックマークを指定するためのパラメータがあります。

  • レプリケートされたブックマークをJMS/XLA構成ファイルで指定すると、アプリケーションの起動時にJMS/XLAがブックマークを作成し、ブックマークにサブスクライブします。(「JMS/XLA構成ファイルおよびトピック」も参照してください。)

次の使用上のノートに注意してください。

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

  • レプリケートされるブックマークが存在していても、アクティブ・スタンバイ・ペア・スキームは削除できます。ブックマークはその時点でレプリケートされなくなりますが、削除はされません。続けてアクティブ・スタンバイ・ペア・スキームを再度有効にすると、これらのブックマークは自動的にスキームに追加されます。

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

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

XLAブックマークおよびトランザクション・ログの保持

XLAの使用時、XLAブックマークが進行するまで、TimesTenトランザクション・ログ・ファイルは保持されることを認識しておく必要があります。

この保持により、XLAによって必要がないと判断されるまで、トランザクション・ログ・ファイルはパージされません。XLAアプリケーションが予期せず終了したり、そのブックマークの削除や変更トラッキングの無効化を行わずに切断した場合などに、ブックマークが固まってしまうと、ログは保持されたままになり、トランザクション・ログ・ファイルが過度に蓄積される場合があります。この蓄積により、ファイル・システム領域が一杯になる場合があります。

『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』トランザクション・ログ・ファイルの蓄積の監視を参照してください。

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

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

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

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

次のコードは、構成ファイルをInitialContextクラスの環境変数の一部として指定します。

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構成ファイルを検索します。この例では、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では、最初に見つかった構成ファイルを使用します。

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

<xlaconfig>
  <topics>
    <topic name="DemoDataStore"
      connectionString="DSN=TestDB"
      xlaPrefetch="100" />
  </topics>
</xlaconfig>

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

<xlaconfig>
  <topics>
    <topic name="DemoDataStore"
      connectionString="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

順序が作成されました。

DROP_SEQ

順序が削除されました。

CREATE_SYNONYM

順序が作成されました。

DROP_SYNONYM

順序が削除されました。

TRUNCATE

表内のすべての行が削除されています。

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

XLA更新確認

この項では、JMS/XLAでの更新の確認について説明します。

XLA応答メカニズム

XLAの応答のメカニズムでは、アプリケーションのメッセージの受信だけでなく、メッセージの正常な処理も確認するように設計されています。

永続的に更新を応答すると、アプリケーションのXLAブックマークは、読み取られた最終レコードにリセットされます。これにより、以前に返されたレコードが再読み取りされないようになり、アプリケーションがXLAに再接続する場合にブックマークが再利用されるときに、アプリケーションがレコードの新しいバッチのみを受信するようになります。

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

XLA応答モード

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

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

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

    xlaprefetchの設定例は、「JMS/XLA構成ファイルおよびトピック」を参照してください。

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

次の例では、応答モードを設定します。

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

「更新確認の頻度の減少」も参照してください。

更新のプリフェッチ

複数の更新レコードを一度にプリフェッチする処理は、XLAから各更新レコードを個々に取得する処理より効率的です。

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

更新の確認

XLA更新に明示的に応答するには、更新メッセージでacknowledge()をコールします。

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

XLAシステム権限

XLAユーザーには、XLAシステム権限が必要です。

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

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

XLAの制限事項

TimesTenのJMS/XLAを使用する場合のXLAの制限事項について知っておいてください。

  • JMS/XLAは、TimesTenでサポートされているすべてのプラットフォームで使用できます。ただし、XLAは異なるプラットフォーム間のデータ転送はサポートしていません。

  • LOBに対するJMS/XLAサポートは限定されています。「表への更新の監視」を参照してください。

  • JMS/XLAでは、ドライバ・マネージャ・ライブラリまたはクライアント/サーバー・ライブラリにリンクされたアプリケーションはサポートされていません。

  • XLAリーダーは、インメモリー列ベースの圧縮を使用する表をサブスクライブできません。

  • Oracle Databaseに対する変更トラッキング・トリガーでは、自動リフレッシュ・キャッシュ・グループの列レベルでの解決は行いません。(これは非常に高コストになります。)そのため、自動リフレッシュ機能は行のすべての列を更新し、実際にはすべての列のデータが変更されていない場合でも、XLAではすべての列が変更されたというレポートのみが行われます。

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 timesten_home/install/lib
$ java -cp ./orai18n.jar oracle.i18n.util.GDKOracleMetaData -version

「Java開発のためのクラスパスの設定」も参照してください。

ノート:

パスtimesten_home/installinstallation_dirへのシンボリック・リンクです。