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のほとんどの概念を示す次の例を検討してください。
この例では、トランザクション・ログに次のレコードが含まれています。
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メカニズムとの間に、処理上の違いはありません。
マテリアライズド・ビューの詳細は、次を参照してください。
-
『Oracle TimesTen In-Memory Database SQLリファレンス』のCREATE MATERIALIZED VIEW
-
『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のマテリアライズド・ビューの理解
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構成ファイルおよびトピック」を参照してください。
レプリケートされるブックマークでは、ブックマークへの操作が必要に応じてスタンバイ・データベースにレプリケートされるため、スタンバイに対する必要な書き込み権限があることを想定しています。これにより、フェイルオーバーが発生した場合、より効率的にブックマークの位置をリカバリできます。
レプリケートされたブックマークを使用する際には、次の順でステップを実行する必要があります。
- アクティブ・スタンバイ・ペアのレプリケーション・スキームを作成します。(これは
create active standby pair
操作、またはクラスタウェア管理環境のttCWAdmin -create
コマンドによって行われます。) - ブックマークを作成します。
- ブックマークをサブスクライブします。
- アクティブ・スタンバイ・ペアを起動します(このとき、スタンバイへの複製が発生し、レプリケーションが始まります)。(これは
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更新タイプ
更新タイプ | 説明 |
---|---|
|
行が追加されました。 |
|
行が変更されました。 |
|
行が削除されました。 |
|
トランザクションがコミットされました。 |
|
表が作成されました。 |
|
表が削除されました。 |
|
索引が作成されました。 |
|
索引が削除されました。 |
|
新規の列が表に追加されました。 |
|
列が表から削除されました。 |
|
マテリアライズド・ビューが作成されました。 |
|
マテリアライズド・ビューが削除されました。 |
|
順序が作成されました。 |
|
順序が削除されました。 |
|
順序が作成されました。 |
|
順序が削除されました。 |
|
表内のすべての行が削除されています。 |
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システム権限
XLAユーザーには、XLA
システム権限が必要です。
-
XLA機能を実行するには、システム権限
XLA
が必要です。これには、TimesTenにXLAリーダーとして接続して(これにはCREATE SESSION
権限も必要)、TimesTen XLA組込みプロシージャttXlaBookmarkCreate
、ttXlaBookmarkDelete
、ttXlaSubscribe
およびttXlaUnsubscribe
(これらについては、『Oracle TimesTen In-Memory Databaseリファレンス』の組込みプロシージャを参照)を実行することも含まれます。 -
XLA
権限を持つユーザーは、SELECT ANY TABLE
、SELECT 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
/install
はinstallation_dir
へのシンボリック・リンクです。