JMS/XLAの使用と機能

JMS/XLAを使用する場合の重要な側面を示します。

XLAへの接続

XLAに接続して更新を受信するには:

  1. 初期コンテキストの作成時にプロパティ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は、CLASSPATHdownload-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プロバイダを使用します。JAR jakarta.jms-api-3.1.0.jarおよびjakarta.jms-api-3.0.0.jarには、Jakarta Messaging APIバージョン1.1プロバイダに必要なクラスjakarta.jms.TopicConnectionFactoryが含まれています。「Java開発のためのクラスパスの設定」を参照してください。

  2. JMS接続ファクトリを使用して、接続を作成します。
  3. この接続を使用して、セッションを確立します。
  4. 更新の処理を開始する準備ができたら、接続で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更新は、同期または非同期に受信できます。

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

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

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

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

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

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

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

  3. TopicSubscriberMessageListenerを登録します。

  4. 接続を開始します。

    ノート:

    接続を開始する前にMessageListenerを登録しないと、メッセージを受信できない場合があります。接続済の場合は、接続を停止してMessageListenerを登録した後に、接続を再開します。

  5. メッセージを受信するまで待機します。アプリケーションがメイン・スレッド内で行う処理が他にない場合は、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 TopicSessionunsubscribe()をコールして、アプリケーションの停止時にそのサブスクライバが使用した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の使用」を参照してください。