JMS/XLAの使用と機能
JMS/XLAを使用する場合の重要な側面を示します。
XLAへの接続
XLAに接続して更新を受信するには:
- 初期コンテキストの作成時にプロパティ
Context.INITIAL_CONTEXT_FACTORY
を使用して、アプリケーションでJMS APIバージョン1.1を使用するか、Jakarta Messaging APIバージョン1.1を使用するかに応じて、適切なJMS接続ファクトリを作成します。- Jakarta Messaging APIバージョン1.1では、値
com.timesten.dataserver.jakartajmsxla.SimpleInitialContextFactory
を使用します。 - JMS APIバージョン1.1の場合は、値
com.timesten.dataserver.jmsxla.SimpleInitialContextFactory
を使用します。
このプロパティが指定されていない場合、TimesTen JMS/XLAは、
CLASSPATH
にdownload-directory/jakarta.jms-api-3.1.0.jar
またはdownload-directory/jakarta.jms-api-3.0.0.jar
が存在しないかぎり、JMS APIバージョン1.1プロバイダにデフォルト設定されます。この場合、TimesTen JMS/XLAはJakarta Messaging APIバージョン1.1プロバイダを使用します。JARjakarta.jms-api-3.1.0.jar
およびjakarta.jms-api-3.0.0.jar
には、Jakarta Messaging APIバージョン1.1プロバイダに必要なクラスjakarta.jms.TopicConnectionFactory
が含まれています。「Java開発のためのクラスパスの設定」を参照してください。 - Jakarta Messaging APIバージョン1.1では、値
- JMS接続ファクトリを使用して、接続を作成します。
- この接続を使用して、セッションを確立します。
- 更新の処理を開始する準備ができたら、接続で
start()
をコールしてメッセージの配信を有効にします。
次の例は、TimesTen Classicクイック・スタート・サンプル・アプリケーションのJakarta JMSのasyncJMS2
サンプル・プログラムからのものです。「TimesTenクイック・スタートおよびサンプル・アプリケーションについて」を参照してください。
/** JMS connection */
private jakarta.jms.TopicConnection connection;
...
//jakarta jms
Properties props = new Properties();
props.setProperty(Context.INITIAL_CONTEXT_FACTORY,
"com.timesten.dataserver.jakartajmsxla.SimpleInitialContextFactory");
// get Connection
Context messaging = new InitialContext(props);
TopicConnectionFactory connectionFactory = (TopicConnectionFactory)messaging.lookup("TopicConnectionFactory");
connection = connectionFactory.createTopicConnection();
connection.start();
// get Session
log("create session");
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);
...
JavaX JMSについては、かわりにTimesTenクラシック・クイック・スタートのasyncJMS
サンプル・プログラムを参照してください。
表への更新の監視
更新の受信を開始する前に、変更の監視対象となる表をXLAに知らせる必要があります。
変更をサブスクライブして、表に対するXLAパブリッシングをオンにするには、JDBCを介してttXlaSubscribe
組込みプロシージャをコールします。
ttXlaSubscribe
を使用して表に対するXLAパブリッシングを有効にする場合は、次のように表を追跡するときに使用されるパラメータ(表の名前とブックマークの名前)を指定する必要があります。
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組込みプロシージャの使用の詳細は、「プロシージャおよびファンクションを実行するためのCALLの使用」を参照してください。
ノート:
JMS/XLAでのLOBのサポートは、次のとおり限定されています。
-
LOB列を含む表はサブスクライブできますが、LOB値自体の情報は入手できません。
-
LOBを含む列は空(長さがゼロ)またはnull(値が実際に
NULL
の場合)とレポートされます。この方法では、null列と非null列の違いがわかります。
その他の注意事項については、次の「更新の受信および処理」の項を参照してください。
更新の受信および処理
XLA更新は、同期または非同期に受信できます。
同期をとってトピックの更新を受信および処理するには、次のタスクを実行します。
-
永続
TopicSubscriber
インスタンスを作成してトピックをサブスクライブします。 -
サブスクライバで
receive()
またはreceiveNoWait()
をコールして、次に使用可能な更新を取得します。 -
返された
MapMessage
インスタンスを処理します。
トピックの更新を非同期に受信および処理するには、次の手順を実行します。
-
更新を処理する
MessageListener
インスタンスを作成します。 -
永続
TopicSubscriber
インスタンスを作成してトピックをサブスクライブします。 -
TopicSubscriber
にMessageListener
を登録します。 -
接続を開始します。
ノート:
接続を開始する前に
MessageListener
を登録しないと、メッセージを受信できない場合があります。接続済の場合は、接続を停止してMessageListener
を登録した後に、接続を再開します。 -
メッセージを受信するまで待機します。アプリケーションがメイン・スレッド内で行う処理が他にない場合は、
Object
メソッドwait()
をコールしてメッセージを待機できます。
更新がパブリッシュされると、MessageListener
メソッドonMessage()
がコールされ、メッセージがMapMessage
インスタンスとして渡されます。
SYS.XLASUBSCRIPTIONS
システム表を確認することで、アプリケーションで表のサブスクリプションを検証できます。
ノート:
XLAでのLOBのサポートは、限定されています。BLOBフィールドにはMapMessage
メソッドのgetBytes()
を使用し、CLOBまたはNCLOBフィールドにはgetString()
を使用することによって更新メッセージでLOBフィールドにアクセスできますが、これらのフィールドには長さが0のデータが含まれる場合があります(または値が実際NULL
の場合はnullデータが含まれます)。
次の例では(asyncJMS
TimesTen Classicクイック・スタート・サンプル・アプリケーション)、更新を非同期に処理するようにリスナーを使用します。
MyListener myListener = new MyListener(outStream);
outStream.println("Creating consumer for topic " + topic);
Topic xlaTopic = session.createTopic(topic);
bookmark = "bookmark";
TopicSubscriber subscriber = session.createDurableSubscriber(xlaTopic, bookmark);
// After setMessageListener() has been called, myListener's onMessage
// method is called for each message received.
subscriber.setMessageListener(myListener);
bookmark
はすでに存在している必要があります。JDBCおよびttXlaBookmarkCreate
組込みプロシージャを使用して、ブックマークを作成できます。また、TopicSubscriber
は、永続サブスクライバである必要があります。XLA接続は永続的であるように設計されています。XLAブックマークによって、トピックからの切断が可能になり、更新が中断した位置から更新の受信を開始するために、再度接続することもできます。永続サブスクライバの作成時にサブスクリプション識別子として渡す文字列は、XLAブックマーク名として使用されます。
JMS TopicSession
でunsubscribe()
をコールして、アプリケーションの停止時にそのサブスクライバが使用したXLAブックマークを削除できます。これによって、アプリケーションの再起動時に、新しいブックマークが作成されます。
更新を受信すると、MapMessage
取得メソッドを使用してメッセージから情報を抽出し、アプリケーションで必要な処理を行うことができます。TimesTen XlaConstants
クラスでは、XLA更新メッセージの処理に使用にするために、更新タイプおよび特別なメッセージ・フィールドの定数が定義されています。
通常、メッセージに含める更新タイプを最初に決定します。MapMessage
メソッドgetInt()
を使用して__TYPE
フィールドの内容を取得し、XlaConstants
クラスで定義されている数値定数とその値を比較します。
次の例では(asyncJMS
TimesTen Classicクイック・スタート・サンプル・アプリケーション)、メソッドonMessage()
はMapMessage
オブジェクトから更新タイプを抽出し、更新が示している処理を表示します。
public void onMessage(Message message)
{
MapMessage mapMessage = (MapMessage)message;
String messageType = null;
/* Standard output stream */
private static PrintStream outStream = System.out;
if (message == null)
{
errStream.println("MyListener: update message is null");
return ;
}
try
{
outStream.println();
outStream.println("onMessage: got a " + mapMessage.getJMSType() + " message");
// Get the type of event (insert, update, delete, drop table, etc.).
int type = mapMessage.getInt(XlaConstants.TYPE_FIELD);
if (type == XlaConstants.INSERT)
{
outStream.println("A row was inserted.");
}
else if (type == XlaConstants.UPDATE)
{
outStream.println("A row was updated.");
}
else if (type == XlaConstants.DELETE)
{
outStream.println("A row was deleted.");
}
else
{
// Messages are also received for DDL events such as CREATE TABLE.
// This program processes INSERT, UPDATE, and DELETE events,
// and ignores the DDL events.
return ;
}
...
}
...
}
受信したメッセージのタイプがわかれば、アプリケーションにおける必要性に応じて、メッセージを処理できます。メッセージのすべてのフィールドのリストを取得するには、MapMessage
メソッドgetMapNames()
をコールします。メッセージの個々のフィールドを名前ごとに取得できます。
次の例では(asyncJMS
TimesTen Classicクイック・スタート・サンプル・アプリケーション)、列名を使用して挿入、更新および削除メッセージから列値を抽出します。
/* Standard output stream */
private static PrintStream outStream = System.out;
...
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");
outStream.println("New Column Values:");
outStream.println("cust_num=" + cust_num);
outStream.println("region=" + region);
outStream.println("name=" + name);
outStream.println("address=" + address);
}
XLA更新メッセージの内容の詳細は、「JMS/XLAのMapMessageの内容」を参照してください。TimesTenの列の型がどのようにJMSデータ型にマップされるか、および列値を取得するために使用する取得メソッドについては、「データ型のサポート」を参照してください。
JMS/XLAアプリケーションの終了
アプリケーションでトランザクション・ログからの読取りが終了したときにアプリケーションを正常に終了させるための手順を示します。
接続のクローズ
XLAへの接続をクローズするには、Connection
オブジェクトでclose()
をコールします。
接続がクローズされた後、その接続、セッションまたはサブスクライバを使用しようとすると、IllegalStateException
エラーになります。その接続から受信したメッセージを継続して使用できますが、接続がクローズされた後、受信したメッセージのacknowledge()
メソッドをコールすることはできません。
ブックマークの削除
停止時にXLAブックマークを削除するかどうかは、任意に選択できます。ブックマークを削除すると、トランザクション・ログ内の未読の更新レコードに関連するファイル・システム領域を解放できます。
ブックマークを削除しない場合は、永続サブスクライバで再利用できます。永続サブスクライバが再接続するときにブックマークが使用可能な場合、サブスクライバは、以前の接続が終了した後に発行されたすべての未確認の更新を受信します。アプリケーションが読取りを行わないブックマークがある場合は、トランザクション・ログが増大し続け、データベースが消費するファイル・システム領域が増加するので注意してください。
ブックマークを削除するには、JMS Sessionでunsubscribe()
をコールします。これにより、ttXlaBookmarkDelete
組込みプロシージャが起動され、XLAブックマークが削除されます。
ノート:
レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。
表からのサブスクライブ解除
表に対するXLAパブリッシングをオフにするには、ttXlaUnsubscribe
組込みプロシージャを使用します。ttXlaSubscribe
を使用して表に対するXLAパブリッシングを有効にする場合は、アプリケーションを停止するときにttXlaUnsubscribe
を使用して表からのサブスクライブ解除を行う必要があります。
ノート:
表を削除する場合は、まず表からサブスクライブ解除します。
表からのサブスクライブ解除を行う場合は、次のように表を追跡するときに使用される表の名前とブックマークの名前を指定します。
ttXlaUnsubscribe(user.table, mybookmark)
たとえば、CallableStatement
オブジェクトでttXlaUnSubscribe
をコールするには、次の例のようにします。
Connection con;
CallableStatement cStmt;
...
cStmt = con.prepareCall("{call ttXlaUnSubscribe(user.table, mybookmark)}");
cStmt.execute();
「プロシージャおよびファンクションを実行するためのCALLの使用」を参照してください。