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アプリケーションのチューニング」を参照してください。
この章の内容は次のとおりです。
Javaアプリケーションは、JMS/XLA APIを使用してTimesTenからイベント通知を受信できます。JMS/XLAは、JMSパブリッシュ・サブスクライブ・インタフェースを使用してXLA更新へのアクセスを提供します。
XLAへの接続を提供するJMS Session
を確立して永続サブスクライバ(TopicSubscriber
)を作成し、更新をサブスクライブします。このサブスクライバを使用してメッセージを同時に受信および処理したり、リスナー(MessageListener
)を実装して非同期に更新を処理できます。
JMS/XLAは、ローカル・データ・ストアを監視するアプリケーション用に設計されています。 TimesTenおよび通知を受信するアプリケーションは、同じシステム上に存在している必要があります。
注意: JMS/XLA APIでは、永続モードのXLAがサポートされています。 このモードでは、XLAによって更新レコードがトランザクション・ログ・バッファまたはトランザクション・ログ・ファイルから直接取得されるため、それらの更新レコードは読み取られるまで使用可能です。 また、永続モードのXLAを使用すると、複数のリーダーでトランザクション・ログの更新に同時にアクセスできます。 |
この項の内容は次のとおりです。
アプリケーションによってTimesTenデータ・ストアが変更されると、TimesTenは、データに対して行われた変更およびトランザクション・コミットなど、その他のイベントを記述するトランザクション・ログ・レコードを生成します。
生成される新しいトランザクション・ログ・レコードは、常にトランザクション・ログ・バッファの最後に書き込まれます。 トランザクション・ログ・レコードは、メモリ内のログ・バッファからディスク上のトランザクション・ログ・ファイルへ定期的に一括でフラッシュされます。
アプリケーションで、XLAを使用し、TimesTenデータ・ストアへの変更に関してトランザクション・ログを監視できます。XLAは、トランザクション・ログ全体を読み取り、ログ・レコードをフィルタ処理し、目的の表および列への変更が含まれているトランザクション・レコードのリストをXLAアプリケーションに配信します。
XLAは、レコードをディスクリート・トランザクションにソートします。 複数のアプリケーションが同時にデータ・ストアを更新している場合、異なるアプリケーションのトランザクション・ログ・レコードがトランザクション・ログに交互に配置されます。
XLAは、特定のトランザクションに関連するすべてのトランザクション・ログ・レコードを透過的に抽出し、それらを連続するリストにしてアプリケーションに配信します。
コミット済のトランザクションのレコードのみが返されます。コミット済のレコードは、最後のコミット・レコードがトランザクション・ログに書き込まれる順序で返されます。コミットされていないデータ・ストアへの変更に関連するレコードは、XLAによってフィルタ処理されます。
変更が行われ、その後にロールバックされた場合、強制終了されたトランザクションのレコードはアプリケーションに配信されません。
これらのXLAの基本概念のほぼすべてを例3-1に示し、続いてそれぞれの内容を箇条書きで示します。
図3-1に示すトランザクション・ログを例として考えてみます。
例3-1 トランザクション・ログ・レコードの読取り
この例では、トランザクション・ログに次のレコードが含まれています。
表W、YおよびZへの変更を検出するように設定されているXLAアプリケーションでは次のようになります。
この例は、次のことを示します。
アプリケーション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通知の順序が、関連付けられているディテール表に関する順序、または同期ビューに関する順序と同じとはかぎらないことに注意してください。 たとえば、ディテール表に対する挿入が2つある場合、非同期マテリアライズド・ビューでは、これらの2つが逆の順序で実行される可能性があります。 また、更新が、削除してから挿入として処理されたり、複数の挿入や複数の削除など、複数の処理が組み合される可能性があります。 処理の順序を保持する必要があるアプリケーションでは、非同期マテリアライズド・ビューを使用しないでください。
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 を使用してブックマークを作成する場合、このファンクションで、レプリケートされるブックマークを指定する設定ができます。 |
次の点に注意してください。
スタンバイ・データベースのブックマークとアクティブ・データベースのブックマークは非常に近い位置にあります。ただし、応答操作のレプリケーションは非同期であるため、応答操作が実行される頻度によっては、フェイルオーバーのイベント中、重複する更新が小さなウィンドウに表示されることがあります。
アクティブ・スタンバイ・ペア・スキームを有効にしたときに、レプリケートされるブックマークがすでに存在している場合、ブックマークは自動的にレプリケーション・スキームに追加されます。
レプリケートされるブックマークが存在していても、アクティブ・スタンバイ・ペア・スキームは削除できます。 ブックマークは、その時点でレプリケートされなくなります。
レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。
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では、最初に見つかった構成ファイルを使用します。
アプリケーションは、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に再接続したときにブックマークが再利用された場合、以前に応答されたレコードをアプリケーションが受信しないようにすることもできます。
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の使用、または更新の明示的な確認が可能になります。各メッセージに対して個々に応答しないようにすると、通常は明示的な更新の応答によって、最も高いパフォーマンスを得ることができます。
「アクセス制御のためのTimesTen機能の検討」では、TimesTenアクセス制御がデータベースの操作に与える影響の概要を提供しています。 アクセス制御は、XLAに次のような影響を与えます。
XLA機能を実行するには、システム権限XLAが必要です。 これには、TimesTenにXLAリーダーとして接続して、ttXlaBookmarkCreate
、 ttXlaBookmarkDelete
、ttXlaSubsribe
およびttXlaUnsubscribe
TimesTen XLA組込みファンクション(『Oracle TimesTen In-Memory Databaseリファレンス』の組込みプロシージャに関する項を参照してください)を実行することも含まれます。
XLA権限を持つユーザーは、SELECT ANY TABLEおよびSELECT ANY SEQUENCEのシステム権限と同等の操作を実行できます。
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に接続するには、JMS ConnectionFactory
を使用してConnection
を作成します。 次に、Connection
を使用してSession
を確立します。 更新の処理を開始する準備ができたら、Connection
のstart
をコールしてメッセージの配信を有効にします。 例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更新は、同期または非同期に受信できます。
トピックの更新を同期をとって受信および処理するには、次の手順を実行します。
永続TopicSubscriber
インスタンスを作成してトピックをサブスクライブします。
サブスクライバでreceive()
またはreceiveNoWait()
をコールして、次に使用可能な更新を取得します。
返されたMapMessage
インスタンスを処理します。
トピックの更新を非同期に受信および処理するには、次の手順を実行します。
更新を処理するMessageListener
インスタンスを作成します。
トピックをサブスクライブする、永続TopicSubscriber
インスタンスを作成します。
TopicSubscriber
にMessageListener
を登録します。
接続を開始します。
注意: 接続を開始する前にMessageListener を登録する必要があります。これを行わないと、メッセージが表示されない可能性があります。 接続済の場合は、接続を停止してMessageListener を登録した後に、接続を再開します。 |
メッセージを受信するまで待機します。 アプリケーションがメイン・スレッド内で行う処理が他にない場合は、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 TopicSession
でunsubscribe()
をコールして、アプリケーションの停止時にそのサブスクライバが使用した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データ型にマップされているか、および列値を取得するために使用する取得メソッドについては、「データ型のサポート」を参照してください。
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組込みプロシージャのコール」を参照してください。
『Oracle TimesTen In-Memory Database TimesTen to TimesTen開発者および管理者ガイド』で説明するTimesTenのレプリケーション・ソリューションが要件を満たしていない場合は、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
メソッドによって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. } }