ヘッダーをスキップ
Oracle Streamsアドバンスト・キューイング・ユーザーズ・ガイド
11gリリース1(11.1)
E05782-01
  目次
目次
索引
索引

戻る
戻る
次へ
次へ
 

11 Oracle JMSの概要

この章では、Oracle Streams Advanced Queuing(AQ)に対するOracle Java Message Service(JMS)インタフェースを説明します。

内容は次のとおりです。

11.1 JMSおよびOracle JMSの一般的な機能

内容は次のとおりです。

11.1.1 JMSコネクションおよびセッション

内容は次のとおりです。

11.1.1.1 ConnectionFactoryオブジェクト

ConnectionFactoryは、管理者によって定義された接続構成パラメータの集合をカプセル化します。クライアントはこれを使用してJMSプロバイダとの接続を確立します。この場合、Oracle Databaseの一部であるOracle JMSがJMSプロバイダです。

ConnectionFactoryオブジェクトには、次の3種類があります。

  • ConnectionFactory

  • QueueConnectionFactory

  • TopicConnectionFactory

11.1.1.2 AQjmsFactoryを使用したConnectionFactoryオブジェクトの取得

AQjmsFactoryクラスを使用して、ConnectionFactoryQueueConnectionFactoryまたはTopicConnectionFactoryオブジェクトに対するハンドルを取得できます。

Point-to-Point操作とパブリッシュ・サブスクライブ操作の両方をサポートしているConnectionFactoryを取得するには、AQjmsFactory.getConnectionFactory()を使用します。QueueConnectionFactoryを取得するには、AQjmsFactory.getQueueConnectionFactory()を使用します。TopicConnectionFactoryを取得するには、AQjmsFactory.getTopicConnectionFactory()を使用します。

ConnectionFactoryQueueConnectionFactoryまたはTopicConnectionFactoryは、ホスト名、ポート番号、SIDドライバまたはJDBC URLおよびプロパティを使用して作成できます。

11.1.1.3 JNDIを使用したConnectionFactoryオブジェクトの検索

JMS管理者は、Lightweight Directory Access Protocol(LDAP)サーバーにConnectionFactoryオブジェクトを登録できます。JMSでJava Naming and Directory Interface(JNDI)の検索を使用可能にするには、次の設定が必要です。

  1. データベースの登録

    Oracle Databaseサーバーのインストール時にデータベースをLDAPサーバーに登録する必要があります。登録にはDatabase Configuration Assistant(DBCA)を使用します。図11-1は、LDAPサーバー内のOracle Streams AQエントリの構造を示しています。ConnectionFactory>情報は、<cn=OracleDBConnections>に格納されています。トピックおよびキューは、<cn=OracleDBQueues>に格納されています。

    図11-1 LDAPサーバー内のOracle Streams AQエントリの構造

    図adque446.gifの説明が続きます
    図adque446.gifの説明

  2. パラメータGLOBAL_TOPIC_ENABLEDの設定

    データベースのGLOBAL_TOPIC_ENABLEDシステム・パラメータをTRUEに設定する必要があります。これによって、Oracle Streams AQで作成されたすべてのキューおよびトピックが自動的にLDAPサーバーに登録されます。このパラメータは、ALTER SYSTEM SET GLOBAL_TOPIC_ENABLED = TRUEを使用して設定できます。

  3. ConnectionFactoryオブジェクトの登録

    データベースを設定してLDAPサーバーが使用できるようになると、JMS管理者はAQjmsFactory.registerConnectionFactory()を使用して、LDAPにConnectionFactoryQueueConnectionFactoryおよびTopicConnectionFactoryの各オブジェクトを登録できます。

    登録には次のいずれかの方法を使用します。

    • 直接LDAPサーバーに接続

      LDAPにコネクション・ファクトリを登録するには、ユーザーにGLOBAL_AQ_USER_ROLEが必要です。

      LDAPに直接接続するには、registerConnectionFactoryメソッドのパラメータに、LDAPコンテキスト、ConnectionFactoryの名前、QueueConnectionFactoryの名前、TopicConnectionFactoryの名前、ホスト名、データベースSID、ポート番号、JDBCドライバ(ThinまたはOCI8)およびファクトリ・タイプ(キューまたはトピック)を含める必要があります。

    • データベース・サーバーを介してLDAPに接続

      ユーザーはOracle Databaseにログインしてから、データベースによるLDAPエントリの更新ができます。ユーザーが、データベースにログインしてこの操作を実行するには、AQ_ADMINISTRATOR_ROLEを取得する必要があります。

      データベースを介してLDAPに接続するには、registerConnectionFactoryメソッドのパラメータに、AQ_ADMINISTRATOR_ROLEを持つユーザーへのJDBCコネクション、ConnectionFactoryの名前、QueueConnectionFactoryの名前、TopicConnectionFactoryの名前、ホスト名、データベースSID、ポート番号、JDBCドライバ(ThinまたはOCI8)およびファクトリ・タイプ(キューまたはトピック)を含める必要があります。

11.1.1.4 JMSコネクション

JMSコネクションは、クライアントとJMSプロバイダの間のアクティブなコネクションを表します。JMSコネクションによって、次に示すいくつかの重要なサービスが実行されます。

  • JMSプロバイダとのオープン・コネクションまたはコネクション・プールのいずれかをカプセル化します。

  • クライアントとプロバイダのサービス・デーモン間のオープンなTCP/IPソケットを表します。

  • コネクション確立時に、クライアントを認証するための構造を提供します。

  • Sessionsを作成します。

  • コネクション・メタデータを提供します。

  • オプションのExceptionListenerをサポートします。

データベースへのJMSコネクションは、createConnection()createQueueConnection()またはcreateTopicConnection()を起動し、ConnectionFactoryオブジェクト、QueueConnectionFactoryオブジェクトまたはTopicConnectionFactoryオブジェクトにそれぞれパラメータusernameおよびpasswordを渡して作成できます。

次に、Connectionオブジェクトでサポートされているメソッドのいくつかを示します。

  • start()

    このメソッドは、着信メッセージの配信を開始または再開します。

  • stop()

    このメソッドは、着信メッセージの配信を一時停止します。Connectionオブジェクトが停止すると、すべてのメッセージ・コンシューマへの配信は禁止されます。また、同期受信のブロックおよびメッセージは、メッセージ・リスナーに配信されません。

  • close()

    このメソッドは、JMSセッションをクローズして、関連付けられたすべてのリソースを解放します。

  • createSession(true, 0)

    このメソッドは、JMS Connectionインスタンスを使用してJMS Sessionを作成します。

  • createQueueSession(true, 0)

    このメソッドはQueueSessionを作成します。

  • createTopicSession(true, 0)

    このメソッドはTopicSessionを作成します。

  • setExceptionListener(ExceptionListener)

    このメソッドは、Connectionの例外リスナーを設定します。問題が非同期でクライアントに通知されます。メッセージを処理するのみのConnectionの場合、その失敗を確認する他の方法はありません。

  • getExceptionListener()

    このメソッドは、このConnectionExceptionListenerを取得します。

JMSクライアントは、通常1つのConnection、1つのSession、多数のMessageProducerおよびMessageConsumerオブジェクトを作成します。現在のバージョンでは、次の場合を除いて、1つのConnectionにつき1つのオープンSessionのみが許可されています。

  • JDBC OCI8ドライバを使用してJMSコネクションを作成する場合

  • ユーザーが、JMSコネクションの作成時にOracleOCIConnectionPoolインスタンスを提供する場合

Connectionは、作成時は停止モードです。この状態では、メッセージをコネクションに配信できません。通常、設定が完了するまで、Connectionは停止モードのままです。設定が完了した時点で、Connectionstart()メソッドがコールされ、メッセージがConnectionコンシューマに到着し始めます。この設定規則によって、設定処理中であっても、メッセージが非同期配信されることによって発生するクライアントの混乱を最小限に抑えることができます。

Connectionを起動し、続けて設定を実行できます。これを実行するクライアントは、設定処理中に非同期メッセージの配信処理の準備をする必要があります。MessageProducerは、Connectionが停止中でもメッセージを送信できます。

11.1.1.5 JMSセッション

JMS Sessionは、メッセージの作成および処理用の単一スレッドのコンテキストです。これは、Java Virtual Machine(JVM)の外でプロバイダ・リソースを割り当てますが、軽量なJMSオブジェクトとみなされます。

Sessionには、次の役割があります。

  • MessageProducerおよびMessageConsumerオブジェクトのファクトリを構成します。

  • 宛先オブジェクト(キュー/トピック)に対するハンドルの取得方法を提供します。

  • プロバイダが最適化したメッセージ・ファクトリを提供します。

  • セッションのMessageProducerおよびMessageConsumerオブジェクトにまたがる作業を組み合せる一連のトランザクションをサポートし、これらを単位に構成します。

  • セッションが処理および作成するメッセージのシリアル順序を定義します。

  • セッションに登録されたMessageListenerオブジェクトの実行をシリアル化します。

Oracle Database 10gでは、JDBC thinまたはJDBC thick(OCI)ドライバのいずれかを使用すると、単一のJMS Connectionを使用して、リソースが許すかぎり多くのJMS Sessionを作成できます。

プロバイダが、JVM外のSessionのためのリソースを割り当てることができるため、クライアントはリソースが必要ないときはこれらを閉じる必要があります。ガベージ・コレクションによる最終的なリソースの解放を待つ必要はありません。Sessionが作成したMessageProducerおよびMessageConsumerオブジェクトについても同様です。

Sessionオブジェクトのメソッドには、次のものが含まれます。

  • commit()

    このメソッドは、トランザクションで実行されるすべてのメッセージをコミットして、現在保持されているロックを解放します。

  • rollback()

    このメソッドは、トランザクションで実行されたすべてのメッセージをロールバックして、現在保持されているロックを解放します。

  • close()

    このメソッドはSessionをクローズします。

  • getDBConnection()

    このメソッドは、基礎となるJDBCコネクションに対するハンドルを取得します。このハンドルを使用して、他のSQL DML操作を同じSessionの一部として実行できます。このメソッドは、Oracle JMSに固有です。

  • acknowledge()

    このメソッドは、非トランザクション・セッションでメッセージの受信を承認します。

  • recover()

    このメソッドは、非トランザクション・セッションでメッセージの配信を再開します。セッション中に配信された一連のメッセージは、最後に承認されたメッセージの後でリセットされます。

Oracle JMSの拡張例は、次のとおりです。

  • createQueueTable()

    このメソッドはキュー表を作成します。

  • getQueueTable()

    このメソッドは既存のキュー表に対するハンドルを取得します。

  • createQueue()

    このメソッドはキューを作成します。

  • getQueue()

    このメソッドは既存のキューに対するハンドルを取得します。

  • createTopic()

    このメソッドはトピックを作成します。

  • getTopic()

    このメソッドは既存のトピックに対するハンドルを取得します。

どの拡張機能を使用する場合も、SessionオブジェクトをAQjmsSessionにキャストする必要があります。


注意:

JMS仕様では、開始されていないJMS Connectionインスタンスで受信が完了したとき、プロバイダによりNULLメッセージが返されることを要求します。

javax.jms.Connectionインスタンスの作成後、start()メソッドをそのインスタンスにコールしてメッセージを受信できるようにする必要があります。コネクション確立後で実際に受信する前に、t_conn.start();などの行を追加するとメッセージを受信できます。


11.1.2 JMS宛先

Destinationは、クライアントがメッセージの送信先および受信元の指定に使用するオブジェクトです。DestinationオブジェクトはQueueまたはTopicに指定できます。Oracle Streams AQでは、特定のデータベースのschema.queueにマップされます。Queueは単一コンシューマ・キューに、Topicはマルチ・コンシューマ・キューにマップします。

11.1.2.1 JMSセッションを使用したDestinationオブジェクトの取得

Destinationオブジェクトは、Sessionオブジェクトからドメイン固有の次のSessionメソッドを使用して作成されます。

  • AQjmsSession.getQueue(queue_owner, queue_name)

    このメソッドはJMSキューに対するハンドルを取得します。

  • AQjmsSession.getTopic(topic_owner, topic_name)

    このメソッドはJMSトピックに対するハンドルを取得します。

11.1.2.2 JNDIを使用したDestinationオブジェクトの検索

LDAPサーバーにスキーマ・オブジェクトを登録するようにデータベースを設定できます。データベースがLDAPを使用できるように設定され、GLOBAL_TOPIC_ENABLEDパラメータがTRUEに設定されている場合、すべてのJMSキューおよびトピックは、作成時に自動的にLDAPサーバーに登録されます。また、管理者は、LDAPに登録されているキューおよびトピックの別名を作成することもできます。LDAPに登録されているキューおよびトピックは、キュー/トピック名またはその別名を使用してJNDIを介して検索できます。

11.1.2.3 JMS宛先メソッド

Destinationオブジェクトのメソッドには、次のものが含まれます。

  • alter()

    このメソッドはキューまたはトピックを変更します。

  • schedulePropagation()

    このメソッドは、ソースから宛先への伝播をスケジューリングします。

  • unschedulePropagation()

    このメソッドは、スケジュール済伝播のスケジュールを解除します。

  • enablePropagationSchedule()

    このメソッドは、伝播スケジュールを有効化します。

  • disablePropagationSchedule()

    このメソッドは、伝播スケジュールを無効化します。

  • start()

    このメソッドはキューまたはトピックを開始します。キューは、エンキューまたはデキューを可能にするために開始されます。トピックは、パブリッシュまたはサブスクライブを可能にするために開始できます。

  • stop()

    このメソッドはキューまたはトピックを停止します。キューは、エンキューまたはデキューを実行不可にするために停止できます。トピックは、パブリッシュまたはサブスクライブを実行不可にするために停止できます。

  • drop()

    このメソッドはキューまたはトピックを削除します。

11.1.3 JMSでのシステム・レベルのアクセス制御

Oracle8i以上では、すべてのキューイング操作に対してシステム・レベルのアクセス制御をサポートします。この機能によって、アプリケーション設計者またはDBAは、ユーザーをキュー管理者にできます。キュー管理者は、データベースのどのキューに対してもJMSインタフェース(管理および操作)を起動できます。これによって、データベース上のキュー全体に対するすべての管理スクリプトを1つのスキーマで管理できるため、管理作業が容易になります。

メッセージが宛先キューに届くと、ソース・キューのスキーマ名に基づいたセッションによって、新しく届いたメッセージが宛先キューにエンキューされます。つまり、ソース・キューのスキーマに宛先キューに対するエンキュー権限を付与する必要があります。

リモートの宛先キューに伝播するために、エージェント構造体のアドレス・フィールドのデータベース・リンクに指定されたログイン・ユーザーには、ENQUEUE_ANY権限を付与するか、または宛先キューに対するエンキュー権限を付与する必要があります。ただし、データベース・リンクのログイン・ユーザーが宛先のキュー表を所有している場合はどのような明示的な権限も付与する必要はありません。

11.1.4 JMSでの宛先レベルのアクセス制御

Oracle8i以上では、エンキューおよびデキュー操作に対してキュー・レベルまたはトピック・レベルのアクセス制御をサポートしています。この機能によって、アプリケーション設計者は、あるスキーマに作成されたキューおよびトピックを他のスキーマで実行中のアプリケーションから保護できます。そのキューまたはトピックが属するスキーマの外で実行しているアプリケーションには、最小限のアクセス権限のみを付与できます。キューまたはトピックに対するアクセス権限として、ENQUEUEDEQUEUEおよびALLがサポートされています。

11.1.5 JMSでの保存およびメッセージ履歴

メッセージは、相互に関連していることがよくあります。たとえば、あるメッセージを処理した結果として他のメッセージが生成された場合、両者は関連付けられています。アプリケーション設計者としては、そのような関連を追跡することが必要な場合があります。Oracle Streams AQでは、ユーザーがメッセージをキュー表に保持し、分析のためにSQLで問合せできます。

保存機能およびメッセージ識別子とともに、メッセージ・ジャーナルがOracle Streams AQによって自動作成され、追跡ジャーナルまたはイベント・ジャーナルをコールできます。保存、メッセージ識別子およびSQL問合せの協調によって、強力なメッセージ・ウェアハウスを構築できます。

11.1.6 JMSでのOracle Real Application Clustersのサポート

Oracle Real Application Clusters(RAC)を使用すると、異なるキューを別々のインスタンスによって管理できるようにすることでOracle Streams AQパフォーマンスを改善できます。このためには、キューを格納するキュー表に様々なインスタンス・アフィニティ(作業環境)を指定します。これによって、様々なキュー/トピックに対するキュー操作(エンキューまたはデキュー)またはトピック操作(パブリッシュ・サブスクライブ)を並行して行うことができるようになります。

Oracle Streams AQのキュー・モニター・プロセスは、キュー表のインスタンス・アフィニティを継続的に監視します。キュー・モニターは指定されたプライマリ・インスタンスが使用可能な場合はそれにキュー表の所有権を割り当て、失敗した場合は指定されたセカンダリ・インスタンスに割り当てます。

キュー表を所有しているインスタンスが終了すると、キュー・モニターはセカンダリ・インスタンスなどの適切なインスタンスに所有者を変更します。

Oracle Streams AQの伝播はReal Application Clustersでも使用できますが、これはユーザーにとっては透過的です。伝播スケジュールのジョブ・アフィニティは、それぞれのキュー表のアフィニティと同じ値に設定されます。このように、キュー表を所有するインスタンスに対応付けられたジョブ・キュー・プロセスは、そのキュー表に格納されているキューからの伝播を処理し、ping操作を最小限に抑えます。


関連項目:


11.1.7 JMSでの統計ビューのサポート

各インスタンスは、それぞれのOracle Streams AQ統計情報をシステム・グローバル領域(SGA)に所有し、他のインスタンスによって収集された統計については認識しません。そのため、インスタンスがGV$AQビューを問い合せると、その他のすべてのインスタンスからそれぞれのその時点の統計情報が問合せ元のインスタンスに集まります。

GV$AQビューは、待機中、準備完了または期限切れの各メッセージ数を必要なときにいつでも問い合せることができます。また、メッセージが処理されるまでの平均待機秒数も表示します。

11.2 JMSでの構造化ペイロード/メッセージの型

JMSメッセージは、ヘッダー、プロパティおよび本体で構成されています。

ヘッダーは、クライアントおよびプロバイダの両方でメッセージの識別およびルーティングに使用される値が含まれるヘッダー・フィールドで構成されています。すべてのメッセージは、同じ一連のヘッダー・フィールドをサポートしています。

プロパティは、オプションのヘッダー・フィールドです。JMSによって定義された標準プロパティの他に、プロバイダ固有およびアプリケーション固有のプロパティを含めることもできます。

本体はメッセージ・ペイロードです。JMSは、様々な型のメッセージ・ペイロードおよびJMSで指定されたメッセージ型のJMSメッセージを格納できる型を定義します。

内容は次のとおりです。

11.2.1 JMSメッセージ・ヘッダー

JMSメッセージ・ヘッダーには、次のフィールドが含まれます。

  • JMSDestination

    このフィールドにはメッセージの送信先が含まれます。Oracle Streams AQでは、宛先キュー/トピックに対応します。これは、Sendメソッドの完了後にJMSによって設定されたDestination型です。

  • JMSDeliveryMode

    このフィールドは、メッセージ・ログを作成するかどうかを決定します。JMSでは、PERSISTENT配信(メッセージが決まった記憶域に記録される)およびNONPERSISTENT配信(メッセージは記録されない)をサポートしています。これは、Sendメソッドの完了後にJMSによって設定されたINTEGER型です。JMSでは、クライアントがJMSDeliveryModeに指定した値を管理者がオーバーライドするようにJMSを構成できます。

  • JMSMessageID

    このフィールドは、プロバイダのメッセージを一意に識別します。すべてのメッセージIDは、ID:で始まる必要があります。これは、Sendメソッドの完了後にJMSによって設定されたString型です。

  • JMSTimeStamp

    このフィールドには、メッセージが送信先のプロバイダに手渡された時刻が含まれます。これは、Oracle Streams AQのメッセージのエンキュー時刻に対応します。これは、Sendメソッドの完了後にJMSによって設定されたLong型です。

  • JMSCorrelationID

    このフィールドを使用して、クライアントはあるメッセージを別のメッセージにリンクできます。これはJMSクライアントによって設定されたString型です。

  • JMSReplyTo

    このフィールドには、メッセージ送信時にクライアントが指定するDestination型が含まれます。クライアントはoracle.jms.AQjmsAgentjavax.jms.Queueまたはjavax.jms.Topicを使用できます。

  • JMSType

    このフィールドには、送信時にクライアントが指定するメッセージ型識別子が含まれます。これはString型です。移植性の観点から、JMSTypeを記号値にすることをお薦めします。

  • JMSExpiration

    このフィールドは、エンキュー時刻および非J2EE準拠モードのTimeToLiveの合計です。準拠モードでは、デキューされたメッセージのJMSExpirationヘッダー値は、メッセージがエンキューされたときのJMSTimeStamp(グリニッジ標準時で1000分の1秒単位)とTimeToLive(1000分の1秒単位)の合計になります。これは、Sendメソッドの完了後にJMSによって設定されたLong型です。JMSでは、クライアントがJMSExpirationに指定した値を管理者がオーバーライドするようにJMSを構成できます。

  • JMSPriority

    このフィールドにはメッセージの優先順位が含まれます。これは、Sendメソッドの完了後にJMSによって設定されたINTEGER型です。J2EE準拠モードで指定できる優先順位の値は09です。Sun社のJMS 1.1標準に準拠した場合、9が最も高い優先順位で、4がデフォルトです。デフォルトは非準拠モードです。管理者は、クライアントがJMSPriorityに指定した値がオーバーライドされるようにJMSを構成できます。

  • JMSRedelivered

    このフィールドは、JMSプロバイダによって設定されたブールです。


関連項目:

「J2EE準拠」

11.2.2 JMSメッセージ・プロパティ

JMSプロパティは、クライアントによって明示的に設定されるか、またはJMSプロバイダによって自動的に設定されます(通常、これらは読取り専用です)。JMSプロパティには、SendおよびReceive操作に指定されたパラメータを使用して設定されるものもあります。

プロパティで、メッセージにオプションのヘッダー・フィールドを追加できます。プロパティによって、クライアントは、messageSelectorを使用して、クライアントのかわりにJMSプロバイダにアプリケーション固有基準を使用してメッセージを選択させることができます。プロパティ名は文字列で、サポートされている値はBooleanByteShortIntegerLongFloatDoubleおよびStringです。

JMS定義のプロパティは、すべてJMSXで始まります。次のものがあります。

  • JMSXUserID

    このフィールドは、メッセージを送信するユーザーの識別情報です。これは、Sendメソッドの完了後にJMSによって設定されたString型です。

  • JMSXAppID

    このフィールドは、メッセージを送信するアプリケーションの識別情報です。これは、Sendメソッドの完了後にJMSによって設定されたString型です。

  • JMSXDeliveryCount

    このフィールドは、メッセージ配信の試行回数です。これは、Sendメソッドの完了後にJMSによって設定されたInteger型です。

  • JMSXGroupid

    このフィールドは、このメッセージが属すメッセージ・グループの識別情報です。これはJMSクライアントによって設定されたString型です。

  • JMSXGroupSeq

    このフィールドは、グループ内のメッセージの順序番号です。これはJMSクライアントによって設定されたInteger型です。

  • JMSXRcvTimeStamp

    このフィールドは、メッセージがコンシューマに配信された時刻(デキュー時刻)です。これは、Receiveメソッドの完了後にJMSによって設定されたString型です。

  • JMSXState

    このフィールドは、プロバイダによって設定されたメッセージ状態です。メッセージ状態は、WAITINGREADYEXPIREDまたはRETAINEDです。

Oracle固有のJMSプロパティは、すべてJMS_Oracleで始まります。次のものがあります。

  • JMS_OracleExcpQ

    このフィールドは、メッセージを元の宛先に配信できない場合に、そのメッセージの送信先となるキュー名です。これはJMSクライアントによって設定されたString型です。JMS_OracleExcpQプロパティに指定できる宛先キューのタイプは、EXCEPTIONのみです。

  • JMS_OracleDelay

    このフィールドは、メッセージ配信の遅延秒数です。これはJMSクライアントによって設定されたInteger型です。これはメッセージが配信されるときの順序に影響します。

  • JMS_OracleOriginalMessageId

    メッセージがある宛先から他の宛先に伝播される場合、このフィールドはソース内のメッセージのメッセージIDに設定されます。これはJMSプロバイダによって設定されたString型です。メッセージが伝播されない場合、このプロパティはJMSMessageIdと同じ値になります。

クライアントは、プロパティを定義することによって、メッセージにヘッダー・フィールドを追加できます。これらのプロパティをmessageSelectorで使用して特定のメッセージを選択できます。

11.2.3 JMSメッセージ本体

JMSでは、次の5つのフォーマットのメッセージ本体が提供されます。

11.2.3.1 StreamMessage

StreamMessageオブジェクトは、Java基本データ型の値をストリームとして送信する場合に使用します。このメッセージ本体には順次書込み/読込みが可能です。StreamMessageMessageから拡張され、StreamMessage本体を追加します。このメソッドは、主にjava.io.DataInputStreamおよびjava.io.DataOutputStreamのメソッドに基づいています。

基本データ型の値は、それぞれの型のメソッドを使用して、明示的に読込みまたは書込みできます。抽象的なオブジェクトとして読込みまたは書込みすることもできます。StreamMessageオブジェクトを使用するには、SYS.AQ$_JMS_STREAM_MESSAGEまたはAQ$_JMS_MESSAGEペイロード型を持つキュー表を作成します。

StreamMessageオブジェクトは、表11-1に示す変換をサポートします。行の型として書き込まれる値は、列の型として読み込むことができます。

表11-1 StreamMessageの変換

Input Boolean Byte Short Char Int Long Float Double String byte[]
Boolean X - - - - - - - X -
Byte - X X - X X - - X -
Short - - X - X X - - X -
Char - - - X - - - - X -
Int - - - - X X - - X -
Long - - - - - X - - X -
Float - - - - - - X X X -
Double - - - - - - - X X -
String X X X X X X X X X -
Byte[] - - - - - - - - - X

11.2.3.2 BytesMessage

BytesMessageオブジェクトは、1つの未解釈バイトのストリームを含むメッセージを送信する場合に使用します。BytesMessageMessageから拡張され、BytesMessage本体を追加します。メッセージの受信者が、そのバイト列を解析します。このメソッドは、主にjava.io.DataInputStreamおよびjava.io.DataOutputStreamのメソッドに基づいています。

これは、クライアントが既存のメッセージ・フォーマットをコード化するためのメッセージ型です。可能であれば、かわりに他の自己定義メッセージ型を使用してください。

Javaの基本データ型の値は、それぞれの型のメソッドを使用して、明示的に書込みができます。また、抽象的なオブジェクトとして書き込むこともできます。BytesMessageオブジェクトを使用するには、SYS.AQ$_JMS_BYTES_MESSAGEまたはAQ$_JMS_MESSAGEペイロード型を持つキュー表を作成します。

11.2.3.3 MapMessage

MapMessageオブジェクトは、名前がString型で値がJava基本データ型である名前/値ペアの集合を送信する場合に使用します。エントリには、名前で順次またはランダムにアクセスできます。エントリの順序は未定義です。MapMessageMessageから拡張され、MapMessage本体を追加します。基本データ型の値は、それぞれの型のメソッドを使用して、明示的に読込みまたは書込みできます。抽象的なオブジェクトとして読込みまたは書込みすることもできます。

MapMessageオブジェクトを使用するには、SYS.AQ$_JMS_MAP_MESSAGEまたはAQ$_JMS_MESSAGEペイロード型を持つキュー表を作成します。MapMessageオブジェクトは、表11-2に示す変換をサポートします。この表の「X」は、行の型として書き込まれる値を列の型として読み取ることができることを意味します。

表11-2 MapMessageの変換

Input Boolean Byte Short Char Int Long Float Double String byte[]
Boolean X - - - - - - - X -
Byte - X X - X X - - X -
Short - - X - X X - - X -
Char - - - X - - - - X -
Int - - - - X X - - X -
Long - - - - - X - - X -
Float - - - - - - X X X -
Double - - - - - - - X X -
String X X X X X X X X X -
Byte[] - - - - - - - - - X

11.2.3.4 TextMessage

TextMessageオブジェクトは、java.lang.StringBufferを含むメッセージを送信する場合に使用します。TextMessageMessageから拡張され、TextMessage本体を追加します。テキスト情報は、getText()およびsetText(...)メソッドを使用して読込みまたは書込みができます。TextMessageオブジェクトを使用するには、SYS.AQ$_JMS_TEXT_MESSAGEまたはAQ$_JMS_MESSAGEペイロード型を持つキュー表を作成します。

11.2.3.5 ObjectMessage

ObjectMessageオブジェクトは、シリアル化可能なJavaオブジェクトを含むメッセージを送信する場合に使用します。ObjectMessageは、Messageから拡張され、単一のJavaオブジェクトへの参照を含む本体を追加します。シリアル化可能なJavaオブジェクトのみを使用できます。Javaオブジェクトのコレクションの送信が必要な場合は、JDK 1.4で提供されたコレクション・クラスの1つを使用できます。このオブジェクトは、getObject()およびsetObject(...)メソッドを使用して読込みまたは書込みができます。ObjectMessageオブジェクトを使用するには、ペイロード型SYS.AQ$_JMS_OBJECT_MESSAGEまたはAQ$_JMS_MESSAGEを持つキュー表を作成します。

11.2.3.6 AdtMessage

AdtMessageオブジェクトは、Oracleのオブジェクト型に対応するJavaオブジェクトを含むメッセージを送信する場合に使用します。これらのオブジェクトはMessageから継承され、CustomDatumまたはORADataインタフェースを実装するJavaオブジェクトを含む本体を追加します。


関連項目:

CustomDatumインタフェースおよびORADataインタフェースの詳細は、『Oracle Database Java開発者ガイド』を参照してください。

AdtMessageオブジェクトを使用するには、Oracleのオブジェクト型としてのペイロード型を持つキュー表を作成します。AdtMessageのペイロードは、getAdtPayloadおよびsetAdtPayloadメソッドを使用して、読取りおよび書込みができます。

AdtMessageオブジェクトを使用してSYS.XMLType型のキューへメッセージを送信することもできます。oracle.xdb.XMLTypeクラスを使用してメッセージを作成する必要があります。

AdtMessageオブジェクトの場合、クライアントが次を取得できます。

  • JMSXDeliveryCount

  • JMSXRecvTimeStamp

  • JMSXState

  • JMS_OracleExcpQ

  • JMS_OracleDelay

11.2.4 異なるメッセージ型でのメッセージ・プロパティの使用

次のメッセージ・プロパティは、クライアントがsetPropertyコールを使用して設定できます。StreamMessageBytesMessageObjectMessageTextMessageおよびMapMessageオブジェクトの場合、クライアントによって次の設定ができます。

  • JMSXAppID

  • JMSXGroupID

  • JMSXGroupSeq

  • JMS_OracleExcpQ

  • JMS_OracleDelay

AdtMessageオブジェクトの場合、クライアントによって次の設定ができます。

  • JMS_OracleExcpQ

  • JMS_OracleDelay

次のメッセージ・プロパティは、クライアントがgetPropertyコールを使用して取得できます。StreamMessageBytesMessageObjectMessageTextMessageおよびMapMessageオブジェクトの場合、クライアントが次を取得できます。

  • JMSXuserID

  • JMSXAppID

  • JMSXDeliveryCount

  • JMSXGroupID

  • JMSXGroupSeq

  • JMSXRecvTimeStamp

  • JMSXState

  • JMS_OracleExcpQ

  • JMS_OracleDelay

  • JMS_OracleOriginalMessageID

11.2.5 Oracle JMSを使用したバッファ済メッセージ

メッセージの送信時にdeliveryModeとしてNON_PERSISTENTを指定すると、非永続JMSメッセージを送信できます。JMS非永続メッセージは決まった記憶域に記録する必要がないため、JMSシステム障害が発生すると消失する可能性があります。JMS非永続メッセージはOracle Streams AQで使用可能になったバッファ済メッセージに類似していますが、両者には重要な相違点も存在します。


注意:

Oracle JMSの非永続メッセージを、Oracle Database 10gリリース2(10.2)で廃止になったOracle Streams AQの非永続キューと混同しないでください。

トランザクションのコミットとクライアントの確認

JMSのdeliveryModeは、メッセージのトランザクション属性と直交します。JMS非永続メッセージは、処理済セッションまたは非処理済セッションで送受信できます。JMS非永続メッセージを処理済セッションで送受信する場合、JMS操作の効果は処理済セッションのコミット後にのみ参照可能です。CLIENT_ACKNOWLEDGE確認モードの非処理済セッションで受信する場合、このメッセージの受信による効果は、クライアントがメッセージを確認した後にのみ参照可能です。確認されない場合、メッセージは削除されず、クライアントがSession.recoverをコールすると再配信されます。

これに対して、Oracle Streams AQのバッファ済メッセージでは、このようなトランザクションまたは確認の概念はサポートされません。バッファ済メッセージの送受信は、どちらもIMMEDIATE可視性モードで実行する必要があります。したがって、セッションがコミットされたかどうかやメッセージが確認されたかどうかは関係なく、ユーザーは送受信操作の効果を即時に参照できます。

各種API

通常のJMS送信およびパブリッシュ・メソッドを使用して送信されたメッセージは、Oracle Streams AQで永続メッセージとして処理されます。通常のJMS受信メソッドは、AQ永続メッセージのみを受信します。 バッファ済メッセージを送受信するには、Oracle拡張APIであるbufferSendbufferPublishおよびbufferReceiveを使用する必要があります。


関連項目:

bufferSendbufferPublishおよびbufferReceiveの詳細は、『Oracle Streams Advanced Queuing Java API Reference』を参照してください。

ペイロード制限

バッファ済メッセージのOracle Streams AQ実装では、LOB属性はサポートされていません。このため、5種類の標準JMSメッセージのペイロードには次の制限が適用されます。

  • JMS TextMessageのペイロードは4000バイト以内です。

    Oracle JMSのキャラクタ・セット変換時には、テキスト・ペイロードをデータベースに格納するためにVARCHARのかわりにCLOBを使用するように控え目な選択が必要になる場合があるため、データベース・キャラクタ・セットによってはこの上限値がさらに低くなる場合があります。

  • JMS BytesMessageのペイロードは2000バイト以内です。

  • JavaでシリアライズされたJMS ObjectMessageStreamMessageおよびMapMessageデータは、2000バイト以内である必要があります。

  • 他のすべてのOracle JMS ADTメッセージの場合、対応するOracleデータベースADTにLOB属性を含めることはできません。

各種定数

表11-3に示すように、Oracle Streams AQとOracle JMSのAPIでは、バッファ済メッセージと永続メッセージの指定に使用される数値が異なります。

表11-3 Oracle Streams AQとOracle JMSのバッファ済メッセージ定数

API 永続メッセージ バッファ済メッセージ
Oracle Streams AQ PERSISTENT := 1 BUFFERED :=2
Oracle JMS PERSISTENT := 2 NON_PERSISTENT := 1

11.3 JMS Point-to-Pointモデル機能

Point-to-Pointモデルでは、クライアントは、1つのポイントから別のポイントへメッセージを交換します。メッセージのプロデューサとコンシューマは、シングル・コンシューマ・キューを使用してメッセージを送受信します。管理者は、AQjmsSessioncreateQueueメソッドを使用して、シングル・コンシューマ・キューを作成します。キューを使用する前に、AQjmsDestinationstartコールを使用して、キューをエンキュー/デキューに対して有効にする必要があります。クライアントは、AQjmsSessiongetQueueメソッドを使用して事前に作成されたキューに対するハンドルを取得します。

シングル・コンシューマ・キューの場合、メッセージは1つのコンシューマが1度のみ処理できます。同じキューから同時にデキューするプロセスまたはオペレーティング・システム・スレッドが複数存在する場合、各プロセスはキューの先頭にあるロックされていない最初のメッセージをデキューします。ロックを作成したプロセス以外のプロセスは、ロックされたメッセージをデキューできません。

処理が済むと、キューの保存期間が0(ゼロ)の場合はそのメッセージは削除され、そうでない場合は指定された期間保存されます。メッセージが保存されている間は、キュー表ビューに対してSQLを使用して問い合せたり、QueueBrowserで処理済メッセージのメッセージ識別子を指定してデキューできます。

QueueSender

クライアントは、QueueSenderを使用して、キューにメッセージを送信します。QueueSenderは、キューをクライアントのSessioncreateSenderメソッドに渡すことで作成されます。また、クライアントにはキューを指定しないで、QueueSenderを作成するオプションがあります。この場合、キューを送信操作のたびに指定する必要があります。

クライアントは、QueueSenderによって送信されたすべてのメッセージのデフォルト配信モード、優先順位およびTimeToLiveを指定できます。または、クライアントはこれらのオプションを各メッセージに対して定義できます。

QueueReceiver

クライアントは、QueueReceiverを使用して、キューからメッセージを受信します。QueueReceiverは、クライアントのSessioncreateQueueReceiverメソッドを使用して作成されます。messageSelectorを使用して作成しても、使用せずに作成してもかまいません。

QueueBrowser

QueueBrowserを使用すると、クライアントはメッセージを削除しないで、キュー上でメッセージを参照できます。このブラウズ用メソッドは、キュー内のメッセージをスキャンするために使用されるjava.util.Enumerationを戻します。nextElementに対する最初のコールが、キューのスナップショットを取得します。QueueBrowserは、messageSelectorを使用して作成しても、使用せずに作成してもかまいません。

QueueBrowserも、メッセージをスキャン中にオプションでロックできます。これは、メッセージに対するSELECT...for UPDATEコマンドの場合と似ています。これによって、他のコンシューマがスキャン中のメッセージを削除することはなくなります。

MessageSelector

messageSelectorによって、クライアントは、コンシューマに配信されるメッセージをmessageSelector式と一致するメッセージに制限できるようになります。TextMessage型、StreamMessage型、BytesMessage型、ObjectMessage型またはMapMessage型のペイロードを含むキューのmessageSelectorには、次の1つ以上を持つ任意の式を含めることができます。

AdtMessage型のペイロードを含むキューのmessageSelectorには、次の1つ以上を持つ任意の式を含めることができます。

11.4 JMSパブリッシュ・サブスクライブ・モデル機能

内容は次のとおりです。

11.4.1 JMSパブリッシュ・サブスクライブの概要

JMSでは、パブリッシャ(出版者)の機能を持つアプリケーションとサブスクライバ(購読者)の役割を果すアプリケーションとの間の柔軟で動的な通信が可能です。アプリケーションが結合されることはなく、メッセージとその内容に基づいて相互に作用します。

メッセージの配信では、パブリッシャ・アプリケーションが明示的にメッセージ受信者を処理または管理する必要はありません。このため、パブリッシャ・アプリケーションの論理を変更しなくても、新しいサブスクライバ・アプリケーションを動的に追加できます。

同様にサブスクライバ・アプリケーションは、メッセージを送信しているパブリッシャ・アプリケーションに関係なく、メッセージの内容に基づいてメッセージを受信します。このため、サブスクライバ・アプリケーションの論理を変更しなくても、新しいパブリッシャ・アプリケーションを動的に追加できます。

サブスクライバ・アプリケーションは、メッセージ・プロパティまたはトピックのメッセージ内容に対してルールベースのサブスクリプション(予約購読)を定義することで、どのようなメッセージに関心があるのかを指定できます。システムは、ルールベースのサブスクリプションを使用して、パブリッシュされたメッセージの受信者を計算し、自動的にルーティングします。

パブリッシュ・サブスクライブ・モデルでは、メッセージはトピックに対してパブリッシュされ、トピックから受信されます。トピックは、AQjmsSessionCreateTopic()メソッドを使用して作成されます。クライアントは、AQjmsSessiongetTopic()メソッドを使用して事前に作成されたトピックに対するハンドルを取得できます。

11.4.2 DurableSubscriber

クライアントは、クライアントのSessioncreateDurableSubscriber()メソッドを使用してDurableSubscriberを作成します。messageSelectorを使用して作成しても、使用せずに作成してもかまいません。

messageSelectorによって、クライアントは、サブスクライバに配信されるメッセージをセレクタにマッチするメッセージに制限できます。セレクタ構文の詳細は、『Oracle Streams Advanced Queuing Java API Reference』のcreateDurableSubscriberに関する項を参照してください。


関連項目:

「MessageSelector」

永続サブスクライバが同じ名前を使用するときのアクションは、実行時にOracle Java Message Service(OJMS)クライアントに設定されるJ2EE準拠モードによって異なります。


関連項目:

「J2EE準拠」

非準拠モードでは、同じ名前の2つの永続的なTopicSubscriberオブジェクトが、2つの異なるトピックに対してアクティブになることができます。準拠モードでは、複数の永続サブスクライバが同じ名前を持つことは許可されません。同じトピックに対して作成された2つのサブスクライバが同じ名前を使用する場合、各サブスクライバに使用されるセレクタが異なると、DBMS_AQJMS.ALTER_SUBSCRIBER()の内部コールを使用して、基になるOracle Streams AQサブスクリプションが変更されます。

2つのサブスクライバが同じ名前を使用し、2つの異なるトピックに対して作成される場合、同じサブスクリプション名を使用するクライアントがそれぞれサブスクリプション名を作成すると、既存のサブスクリプションは削除され新しいサブスクリプションが作成されます。

2つのサブスクライバが同じ名前を使用し、2つの異なるトピックに対して作成される場合、別のクライアント(最初にそのサブスクリプション名を作成したクライアントではない)が既存のサブスクリプション名を使用すると、サブスクリプションは削除されずにエラーが発生します。サブスクリプションがJMSまたはPL/SQLのどちらで作成されたかが不明であるため、その他のトピックについてのサブスクリプションは削除しないでください。

11.4.3 RemoteSubscriber

リモート・サブスクライバは、createRemoteSubscriberコールを使用して定義されます。リモート・サブスクライバは、リモート・トピックでの特定のコンシューマ、またはリモート・トピックでのすべてのサブスクライバになることができます。

リモート・サブスクライバは、AQjmsAgent構造を使用して定義されます。AQjmsAgentは、名前およびアドレスで構成されます。名前は、リモート・トピックのconsumer_nameを参照します。アドレスは、次のようにしてリモート・トピックを参照します。

schema.topic_name[@dblink]

リモート・トピックで特定のコンシューマに対してメッセージをパブリッシュするには、リモート・トピックでの受信者のsubscription_nameが、AQjmsAgentの名前フィールドに指定されている必要があります。リモート・トピックは、AQjmsAgentのaddressフィールドに指定される必要があります。

リモート・トピックのすべてのサブスクライバに対してメッセージをパブリッシュするには、AQjmsAgentのnameフィールドをNULLに設定する必要があります。リモート・トピックは、AQjmsAgentのaddressフィールドに指定される必要があります。

11.4.4 TopicSubscriber

メッセージは、TopiccreatePublisherメソッドに渡すことで作成されるTopicPublisherを使用してパブリッシュされます。クライアントには、Topicを指定しないでTopicPublisherを作成するオプションもあります。この場合、Topicは、パブリッシュ操作のたびに指定する必要があります。クライアントは、TopicPublisherによって送信されたすべてのメッセージのデフォルト配信モード、優先順位およびTimeToLiveを指定できます。各メッセージに対してこれらのオプションを指定することもできます。

11.4.5 受信者リスト

JMSパブリッシュ・サブスクライブ・モデルでは、クライアントは、トピックのすべてのサブスクライバにメッセージを送信するのではなく、明示的な受信者リストを指定できます。これらの受信者は、トピックの既存のサブスクライバである場合もあれば、そうでない場合もあります。受信者リストは、このメッセージのトピックのサブスクリプション・リストをオーバーライドします。受信者リスト機能は、JMSに対するOracleの拡張です。

11.4.6 TopicReceiver

受信者名が受信者リストに明示的に指定されていても、その受信者がキューのサブスクライバではない場合、その受信者に送信されるメッセージは、TopicReceiverを作成することによって受信できます。サブスクライバ名が指定されていない場合、クライアントがメッセージを受信するには、リモート・サイトで永続サブスクライバを使用する必要があります。TopicReceiverは、JMSに対するOracleの拡張です。

TopicReceiverは、messageSelectorを使用して作成できます。これによって、クライアントは、受信者に配信されるメッセージをセレクタにマッチするメッセージに制限できます。


関連項目:

「MessageSelector」

11.4.7 TopicBrowser

TopicBrowserを使用すると、クライアントはメッセージを削除しないでトピック上でメッセージを参照できます。このブラウズ用メソッドは、トピック・メッセージをスキャンするために使用されるjava.util.Enumerationを戻します。TopicBrowserを作成できるのは、永続サブスクライバのみです。nextElementに対する最初のコールが、トピックのスナップショットを取得します。

TopicBrowserは、メッセージをスキャン中にオプションでロックできます。これは、メッセージに対するSELECT...for UPDATEコマンドの場合と類似しています。これによって、他のコンシューマがスキャン中のメッセージを削除することはなくなります。

TopicBrowserは、messageSelectorを使用して作成できます。これによって、クライアントは、コンシューマに配信されるメッセージをセレクタにマッチするメッセージに制限できるようになります。


関連項目:

「MessageSelector」

TopicBrowserは、パージ機能をサポートしています。これによって、TopicBrowserを使用するクライアントは、トピックの現行のブラウズ操作中に参照されたすべてのメッセージを廃棄できます。パージとは、参照済のすべてのメッセージを破壊的に受信することと同じです(TopicSubscriberを使用して削除した場合と似ています)。

パージでは、メッセージがTopicBrowserjava.lang.EnumerationnextElement()操作へのコールを使用してクライアントに戻された場合、そのメッセージは参照済とみなされます。クライアントがまだ参照していないメッセージは、パージ中には廃棄されません。パージ操作は、同じTopicBrowserに対して何度も実行できます。

TopicBrowserの作成に使用したJMS Sessionがコミットされると、パージは正常に実行されます。セッションに対する操作がロールバックされた場合、パージ操作も取り消されます。

11.4.8 JMSパブリッシュ・サブスクライブ操作の設定

JMSでパブリッシュ・サブスクライブ・モデルの通信を使用する手順は、次のとおりです。

  1. メッセージを保持するために1つ以上のトピックを設定します。これらのトピックは、関心がある領域またはサブジェクトを表します。たとえば、トピックで請求済注文情報を表すことができます。

  2. AQjmsDestinationstartコールを使用して、トピックに対するエンキュー/デキューを有効にします。

  3. 永続サブスクライバのセットを作成します。各サブスクライバは、受信を希望するメッセージを選択するmessageSelectorを指定できます。NULLのmessageSelectorは、そのトピックに対してパブリッシュされたすべてのメッセージの受信をサブスクライバが希望していることを示します。

    サブスクライバはローカルでもリモートでもかまいません。ローカル・サブスクライバは、メッセージがパブリッシュされるトピックと同じトピックに対して定義された永続サブスクライバです。リモート・サブスクライバは、特定のキューのサブスクライバとして定義された別のトピックまたはそのトピックに対する受信者です。リモート・サブスクライバを使用するには、ソース・トピックと宛先トピック間の伝播を設定する必要があります。リモート・サブスクライバと伝播は、JMSに対するOracleの拡張です。


    関連項目:

    「伝播の管理」

  4. パブリッシャのSessioncreatePublisher()メソッドを使用してTopicPublisherオブジェクトを作成します。メッセージは、publishコールを使用してパブリッシュされます。メッセージは、トピックのすべてのサブスクライバ、またはトピックに対する指定された受信者のサブセットに対してパブリッシュできます。

  5. サブスクライバは、receiveメソッドを使用してトピックに関するメッセージを受信します。

  6. サブスクライバは、メッセージ・リスナーを使用して、非同期にメッセージを受信することもできます。

11.5 JMS MessageProducerの機能

11.5.1 メッセージの優先順位および順序付け

メッセージの順序付けとは、キューまたはトピックからメッセージが受信される順序を示します。優先順位の指定は、キューまたはトピックに対してキュー表が作成されるときに指定されます。現在、Oracle Streams AQではメッセージ優先順位とエンキュー時刻の順序付けをサポートしています。順序付けには、次の4つの方法があります。

  • First-In, First-Out(FIFO)

    エンキュー時刻が順序付け基準として選択されると、メッセージはエンキュー時刻の順序で受信されます。エンキュー時刻は、メッセージのパブリッシュ/送信時にOracle Streams AQによってメッセージに割り当てられます。これはデフォルトの順序付けです。

  • 優先順位による順序付け

    優先順位による順序付けが選択されると、各メッセージに優先順位が割り当てられます。優先順位は、パブリッシュ/送信時にメッセージ・プロデューサによってメッセージ・プロパティとして指定できます。メッセージは、割り当てられた優先順位の順序で受信されます。

  • FIFO優先順位

    FIFO優先順位による順序付けが選択されると、トピックまたはキューは優先順位による順序付けの場合と同様に機能します。2つのメッセージに同じ優先順位が割り当てられた場合、両者はエンキュー時刻の順に受信されます。

  • エンキュー時刻に続く優先順位による順序付け

    同じエンキュー時刻のメッセージは、そのメッセージの優先順位に従って受信されます。2つのメッセージの順序付け基準が同じ場合、受信される順序は予想できません。ただし、1つのセッション中に特定の順序付け基準で生成されたメッセージは、送信された順序で受信されることがOracle Streams AQにより保証されます。

11.5.2 メッセージ遅延の指定

メッセージをキュー/トピックに対して送信/パブリッシュするときに、遅延を指定できます。遅延は、そのメッセージがメッセージ・コンシューマに対して使用可能になるまでの時間を表します。遅延指定されたメッセージは、遅延の期限が切れるまで待機状態になります。遅延指定は、メッセージ識別子による受信でオーバーライドされます。

遅延は、JMSメッセージ・プロパティに対するOracle Streams AQの拡張機能です。遅延の場合、Oracle Streams AQ用のバックグラウンド処理キュー・モニターを起動する必要があります。

11.5.3 メッセージ期限切れの指定

メッセージのプロデューサは、メッセージの期限切れまたはTimeToLiveを指定できます。これによって、そのメッセージがメッセージ・コンシューマに対して使用可能な期間が定義されます。

TimeToLiveは、送信/パブリッシュ時に指定するか、またはMessageProducerTimeToLiveメソッドを使用して指定できます。前者が優先されます。Oracle Streams AQのバックグラウンド処理キュー・モニターを実行して、TimeToLiveを実装する必要があります。

11.5.4 メッセージのグループ化

1つのキュー/トピックに属しているメッセージをグループ化して1つのセットにし、一度に1コンシューマ以外は使用できないようにできます。そのためには、トランザクションでのメッセージのグループ化に対応したキュー表に、そのキュー/トピックを作成する必要があります。1つのグループに属するすべてのメッセージは、同じトランザクションで作成される必要があります。また、1つのトランザクションで作成されるすべてのメッセージは、同じグループに属します。

メッセージのグループ化は、JMS仕様に対するOracle Streams AQの拡張機能です。

この機能を使用すると、複雑なメッセージを、リンクされた一連の単純なメッセージに分割できます。たとえば、請求書キュー宛ての請求書は、ヘッダーのメッセージ、詳細情報の複数のメッセージ、フッターのメッセージの順に分割できます。

小さいオブジェクトに分割できるイメージやビデオなどの複合LOBがメッセージ・ペイロードにある場合は、メッセージのグループ化が非常に有効です。

グループに含まれるメッセージの優先順位、遅延および期限切れの各プロパティは、単にグループの最初のメッセージ(ヘッダー)のプロパティによってのみ判断されます。グループの他のメッセージのプロパティは無視されます。

メッセージ・グループは、伝播中も保持されます。宛先トピックは、トランザクション処理のグループ化に対して使用可能にしておく必要があります。


関連項目:

トランザクション処理でグループ化可能なキューからメッセージをデキューするときにメッセージ・グループを保持する場合、注意する必要がある制限については、「デキュー機能」を参照してください。

11.6 JMSメッセージ・コンシューマ機能

内容は次のとおりです。

11.6.1 メッセージの受信

JMSアプリケーションは、メッセージ・コンシューマを作成することによって、メッセージを受信できます。メッセージは、receiveコールを使用して同期的に受信するか、メッセージ・リスナーを使用して非同期的に受信できます。

受信モードには次の3つがあります。

  • メッセージがコンシューマに届くまでブロック

  • 指定最大時間までブロック

  • 非ブロック

11.6.2 受信におけるメッセージのナビゲーション

コンシューマがナビゲーション・モードを指定しない場合、セッションの最初のreceiveはキューまたはトピックの最初のメッセージを取り出し、第2のreceiveは次のメッセージを取得します。優先順位が高いメッセージがコンシューマに届く場合、すでに届いているメッセージを削除するまで、コンシューマはこのメッセージを受信しません。

コンシューマが、メッセージに対してより効率的にキューのナビゲーションを制御できるように、Oracle Streams AQにはJMS拡張機能として複数のナビゲーション・モードが用意されています。これらのモードは、TopicSubscriberQueueReceiverまたはTopicReceiverで設定できます。

グループ化されていないメッセージには、次の2つのモードを使用できます。

  • FIRST_MESSAGE

    このモードでは、位置がキューの先頭にリセットされます。このモードでは、コンシューマによるキューの最上位にあるメッセージの削除が許可されているため、優先順位によって順序付けられたキューに有効です。

  • NEXT_MESSAGE

    このモードは、コンシューマの確立された位置の後のメッセージを取得します。たとえば、4番目のメッセージの位置で適用されたNEXT_MESSAGEは、そのキューの5番目のメッセージを取得します。これはデフォルトのアクションです。

グループ化メッセージには、次の3つのモードを使用できます。

  • FIRST_MESSAGE

    このモードでは、位置がキューの先頭にリセットされます。

  • NEXT_MESSAGE

    このモードでは、位置が同一トランザクションの次のメッセージに設定されます。

  • NEXT_TRANSACTION

    このモードでは、位置が次のトランザクションの最初のメッセージに設定されます。

次の方法でメッセージが受信される場合、グループ化トランザクションのプロパティを無効にできます。

  • セレクタに相関識別子を指定して受信

  • セレクタにメッセージ識別子を指定して受信

  • トランザクション・グループのメッセージがすべて受信される前にコミット

NEXT_MESSAGEまたはNEXT_TRANSACTIONオプションの使用中にコンシューマがキューの最後に到達したとします。ブロッキングreceive()を指定していた場合は、ナビゲート位置は自動的にそのキューの先頭に変更されます。

デフォルトでは、QueueReceiverTopicReceiverまたはTopicSubscriberは、最初のreceiveコールにFIRST_MESSAGEを、以降のreceive()コールにNEXT_MESSAGEを使用します。

11.6.3 メッセージのブラウズ

デキューするクライアントがキューからメッセージを削除できる通常のreceiveの他に、JMSでは、JMSクライアントがキューで自身のメッセージをブラウズできるようにするインタフェースを提供しています。QueueBrowserは、QueueSessionからcreateBrowserメソッドを使用して作成できます。

メッセージが参照されると、そのメッセージは引き続き処理できます。メッセージがブラウズされた後は、同時セッションからreceiveコールがそのメッセージを削除する場合があるため、JMSセッションに引き続き使用できるとはかぎりません。

一度参照したメッセージが同時JMSクライアントによって削除されないようにするために、ロック・モードでメッセージを参照できます。そのためには、JMSインタフェースに対するOracle Streams AQの拡張機能を使用して、ロック・モードを持つQueueBrowserを作成する必要があります。メッセージのロックは、セッションがコミットまたはロールバックを実行すると解放されます。

QueueBrowserによって参照されたメッセージを削除するには、セッションがQueueReceiverを作成し、JMSmesssageIDをセレクタとして使用する必要があります。

11.6.4 取出しを伴わないメッセージの削除

コンシューマは、receiveNoDataコールを使用して、メッセージを取り出さないでキューまたはトピックから削除できます。これは、アプリケーションがQueueBrowserを使用してすでにメッセージを調べている場合に便利です。このモードによって、JMSクライアントは、データベースからペイロードを取り出す場合のオーバーヘッドを回避できます。このオーバーヘッドは、大量のメッセージでは相当量になる可能性があります。

11.6.5 遅延間隔をおいた後の再試行

キュー/トピックからメッセージを受信するトランザクションが失敗した場合、そのメッセージを削除する試行に失敗したとみなされます。Oracle Streams AQは、メッセージ削除の試行に失敗した回数をメッセージ履歴に記録します。

アプリケーションでは、メッセージに対する再試行の最大回数をキュー/トピック・レベルで指定できます。メッセージ削除がこの数より多く失敗した場合、メッセージは例外キューに移動されます。

Oracle Streams AQでは、ユーザーはmax_retriesとともにretry_delayも指定できます。これは、受信の試行に失敗したメッセージを、retry_delay間隔後に引き続きキューで参照し、デキューできることを意味します。それまでこのメッセージはWAITING状態になります。Oracle Streams AQのバックグラウンド・プロセスのタイム・マネージャは、再試行遅延プロパティを強制的に適用します。

再試行の最大回数および再試行の遅延は、キュー/トピックのプロパティです。このプロパティは、キュー/トピックの作成時、またはキュー/トピックに対する変更メソッドを使用して設定できます。MAX_RETRIESのデフォルト値は5です。

11.6.6 MessageListenerを使用したメッセージの非同期受信

JMSクライアントは、setMessageListenerメソッドを使用してMessageListenerを設定することによって、メッセージを非同期的に受信できます。

コンシューマにメッセージが届いた場合、メッセージ・リスナーのonMessageメソッドがそのメッセージで起動されます。メッセージ・リスナーは、メッセージの受信をコミットまたは異常終了できます。メッセージ・リスナーは、JMSコネクションが停止されている場合、メッセージを受信しません。一度メッセージ・リスナーがコンシューマに対して設定されると、メッセージの受信にreceiveコールを使用することはできません。

JMSクライアントは、セッションでMessageListenerを設定することによって、そのセッションのすべてのコンシューマに対してメッセージを非同期的に受信できます。一度メッセージ・リスナーが設定されると、そのセッションでは、その他のメッセージ受信モードを使用できません。

11.6.7 例外キュー

例外キューは、期限切れまたは処理できないすべてのメッセージのリポジトリになります。アプリケーションから例外キューには直接エンキューできません。ただし、期限切れまたは処理できないメッセージを処理するアプリケーションは、例外キューからこれらのメッセージを受信または削除できます。

例外キューからメッセージを取り出すには、JMSクライアントはPoint-to-Pointインタフェースを使用する必要があります。トピック用のメッセージの例外キューは、使用可能な複数のコンシューマでキュー表に作成する必要があります。他のキューと同様に、例外キューもAQOracleQueueクラスでstartメソッドを使用して、メッセージを受信できる必要があります。例外キューをエンキュー可能に設定しようとすると、例外が発生します。

例外キューは、「JMS_OracleExcpQ」と呼ばれるOracle固有のメッセージ・プロパティです。これは、メッセージの送信/パブリッシュ前に、そのメッセージで設定できます。例外キューが指定されていないと、デフォルトの例外キューが使用されます。キュー表が作成されると、デフォルトの例外キューがAQ$_queue_table_name_Eという名前で自動的に作成されます。

メッセージは、次の条件が成立するときに例外キューに移されます。

  • そのメッセージが、指定されたtimeToLive内にデキューされなかった場合。

    複数のサブスクライバを指定したメッセージの場合、指定されたtimeToLive内にそのメッセージをデキューできない受信者が1つ以上あると、メッセージは例外キューに移されます。

  • メッセージが正常に受信されたが、メッセージ処理中のエラーのためアプリケーションがreceiveを実行したトランザクションを異常終了した場合。そのメッセージはキュー/トピックに戻され、メッセージ受信のために待機中のどのアプリケーションでも使用可能になります。

    アプリケーションがトランザクション全体を異常終了するか、receive前のセーブポイントまでロールバックしたときは、receiveがロールバックまたはUNDOされたとみなされます。

    これは失敗したメッセージ受信の試行であるため、その再試行回数は更新されます。メッセージの再試行回数が、メッセージが常駐するキュー/トピックに指定された最大値を超える場合、そのメッセージは例外キューに移されます。

    メッセージが複数のサブスクライバを持つ場合、そのメッセージは、すべての受信者が再試行制限を超えたときにのみ、例外キューに移されます。


注意:

サーバー・プロセスがインスタンスで停止した(ALTER SYSTEM KILL SESSIONなど)、またはSHUTDOWN ABORTによってデキュー・トランザクションが失敗した場合、RETRY_COUNTは増分されません。

11.7 JMS伝播

内容は次のとおりです。

11.7.1 RemoteSubscriber

Oracle Streams AQによって、他のデータベースにあるサブスクライバをトピックにサブスクライブできます。トピックに対してパブリッシュされたメッセージがリモート・サブスクライバの基準を満たしている場合は、リモート・サブスクライバに指定されているリモート・データベースにあるキュー/トピックに自動的に伝播します。伝播は、データベース・リンクおよびOracle Net Servicesを使用して実行されます。これによって、同じデータベースに接続しなくても、アプリケーション同士が互いに通信できます。

リモート・サブスクライバを実装するには、次の2つの方法があります。

  • createRemoteSubscriberメソッドは、トピック上またはトピックに対してリモート・サブスクライバを作成するために使用します。このリモート・サブスクライバは、クラスAQjmsAgentのインスタンスとして指定されます。

  • AQjmsAgentには、名前およびアドレスがあります。アドレスは、キュー/トピックおよびサブスクライバのデータベースへのデータベース・リンクで構成されています。

リモート・サブスクライバには、次の2種類があります。

  • リモート・サブスクライバがトピックである場合。

    これは、AQjmsAgentオブジェクトのリモート・サブスクライバに名前が指定されず、アドレスがトピックである場合に発生します。サブスクライバのサブスクリプションを満たすメッセージが、リモート・トピックに伝播されます。伝播されたメッセージは、それが満たすリモート・トピックのすべてのサブスクリプションに対して使用可能になります。

  • メッセージに対して特定のリモート受信者を指定する場合。

    リモート・サブスクリプションは、リモート・データベースにある特定のコンシューマに対して指定できます。リモート受信者の名前が(AQjmsAgentオブジェクトに)指定される場合、サブスクリプションを満たすメッセージが、その受信者専用のリモート・データベースに伝播されます。リモート・データベースにある受信者は、TopicReceiverインタフェースを使用してメッセージを取り出します。リモート・サブスクリプションは、Point-to-Pointキューに対して指定することもできます。

11.7.2伝播スケジュール

伝播は、メッセージがターゲットの接続先データベースに伝播されるすべてのトピックについて、schedule_propagationメソッドを使用してスケジューリングされる必要があります。

スケジュールは時間の枠を示し、メッセージはその枠内でソース・トピックから伝播されます。この時間枠は、ネットワーク通信量、ソース・データベースの負荷、接続先データベースの負荷などの多くの要因に左右されます。したがって、スケジュールは特定のソースおよび宛先にあわせて調整する必要があります。スケジュールが作成されると、ジョブは自動的にjob_queueの機能に発行され、伝播が処理されます。

伝播スケジュールのための運用管理コールによって、スケジュール管理を柔軟に行うことができます。あるスケジュールの存続時間または伝播枠パラメータによって、伝播が開始される時間枠が指定されます。存続時間が指定されない場合、時間枠は無制限の単一枠になります。枠を定期的に繰り返す必要がある場合、連続する枠の間の周期的間隔を定義するnext_time機能を使用して有限の存続時間を指定します。

あるキューに定義された伝播スケジュールは、そのキューの有効期間中いつでも変更または削除できます。さらに、(スケジュールを削除するかわりに)一時的に使用不可にするコール、および使用不可のスケジュールを使用可能にするコールがあります。メッセージがスケジュール内で伝播されているとき、そのスケジュールはアクティブです。すべての管理コールは、スケジュールがアクティブかどうかに関係なく実行されます。スケジュールがアクティブの場合、コールが実行されるまでに数秒かかります。

伝播が開始されるには、ジョブ・キュー・プロセスを起動する必要があります。少なくとも2つのジョブ・キュー・プロセスを起動する必要があります。接続先データベースへのデータベース・リンクも有効にする必要があります。伝播のソースおよび宛先トピックは、同じメッセージ型である必要があります。リモート・トピックは、エンキューできる必要があります。データベース・リンクのユーザーもリモート・トピックに対するエンキュー権限を持つ必要があります。

11.7.3 拡張伝播スケジュール機能

伝播のために定義されたカタログ・ビューは、アクティブ・スケジュールに関する次の情報を提供します。

  • そのスケジュールを処理しているバックグラウンド・プロセスの名前

  • 伝播を処理しているセッションのSID(セッションおよびシリアル番号)

  • スケジュールを処理しているインスタンス(RACを使用している場合)

  • 先行して正常に実行されたスケジュール

  • 次に実行予定のスケジュール

スケジュールごとに次の伝播統計が保持され、キュー管理者がスケジュール調整に役立てることができます。

  • スケジュールの中で伝播されたメッセージ合計数

  • スケジュールの中で伝播されたバイト合計数

  • 伝播枠の中で伝播されたメッセージの最大数

  • 伝播枠の中で伝播されたバイトの最大値

  • 伝播枠の中で伝播されたメッセージの平均数

  • 伝播済メッセージの平均サイズ

  • 伝播済メッセージの平均時間

伝播機能には、障害対処およびエラー・レポートが組み込まれています。たとえば、指定されたデータベース・リンクが無効な場合、リモート・データベースが使用できない場合、またはリモート・トピック/キューにエンキューできない場合、適切なエラー・メッセージがレポートされます。伝播は指数バックオフ・スキームを使用して、障害が発生したスケジュールからの伝播を再試行します。あるスケジュールで続けて障害が発生したときは、最初の再試行は30秒後、次の再試行は60秒後、3回目の再試行は120秒後、というように続きます。再試行時間が現行の伝播枠の期限切れ時刻を超える場合は、次の再試行は、次の伝播枠の開始時刻に行われます。最大16回の再試行が行われた後、そのスケジュールは自動的に使用不可能になります。


注意:

再試行が次の伝播枠にずれ込むと、常にずれ込むようになります。再試行スケジュールは指数バックオフ・スキームでは制御されなくなります。DBMS_AQADM.SCHEDULE_PROPAGATION()next_timeパラメータに指定した日付関数により伝播枠間の間隔が短くなると、再試行の失敗回数がすぐに16を超えてスケジュールが使用不可になります。

障害のためにスケジュールが自動的に使用不可になると、関連情報がアラート・ログに書き込まれます。スケジュールに障害が発生しているかどうか、さらに発生している場合は連続的な障害が何回起きたかということが、最新の障害の原因および発生時刻を示すエラー・メッセージによって確認できます。この情報を調べることで、管理者は障害を回復し、スケジュールを使用可能にできます。

再試行の間に伝播が成功したときは、障害の数は0(ゼロ)にリセットされます。

伝播機能にはReal Application Clustersサポートが組み込まれていますが、ユーザーおよび管理者には透過的です。伝播を処理するジョブは、ソース・トピックが常駐しているキュー表の所有者と同じインスタンスに送られます。あるインスタンスに障害が発生してトピックを保存しているキュー表が他のインスタンスに移される場合は、伝播ジョブも必ず自動的に新しいインスタンスに移行されます。これによって、インスタンス間のping操作は最小限に抑えられ、パフォーマンスが向上します。伝播は、同時スケジュールをいくつでも処理できるように設計されています。

job_queue_processesの最大数は1000で、その一部は伝播に関連しないジョブの処理に使用できます。このために、伝播にはマルチタスキングおよびロード・バランスのサポートが組み込まれています。伝播アルゴリズムは、複数スケジュールが単一スナップショット(job_queue)のプロセスによって処理できるように設計されています。job_queueプロセスに対する伝播の負荷は、異なるソース・トピックからのメッセージ到着の割合に基づいて偏りが発生する場合があります。あるプロセスが数個のアクティブ・スケジュールによって過負荷になっている一方で、別のプロセスは受動的なスケジュールが多いために余力があるというとき、伝播はプロセス間で負荷が均等になるようにスケジュールを自動的に再分配します。

11.7.4 伝播中の例外処理

ネットワーク障害のようなシステム・エラーが発生した場合、Oracle Streams AQは指数バックオフ・アルゴリズムを使用してメッセージを伝播する試みを継続します。キューからデータベース・リンクへの伝播中のアプリケーション・エラーを示している状況では、Oracle Streams AQはそのメッセージにUNDELIVERABLEというマークを付けてalert.logに記録します。このようなエラーは、リモート・キューが存在しない場合、またはソース・キューおよびリモート・キューの型が一致しない場合に発生します。background_dump_destディレクトリのトレース・ファイルには、そのエラーに関する追加情報があります。

新規のジョブ・キュー・プロセスが開始すると、型を再検証できるように型の不一致エラーを消去します。ジョブ・キュー・プロセス数に上限を設定して、伝播のビジー状態が続く場合、ジョブ・キュー・プロセスが終了して再開するまで待つ必要はありません。キューの型は、必要に応じてDBMS_AQADM.VERIFY_QUEUE_TYPESを使用して再検証できます。


注意:

キューからキューへの伝播中に型の不一致が検出されると、伝播は停止してエラーが発生します。このような場合は、DBA_SCHEDULESビューを問い合せて、特定の宛先への伝播中に発生した最後のエラーを判断する必要があります。このメッセージには、UNDELIVERABLEマークは付いていません。

11.8 JMS AQのメッセージ変換

あるフォーマットのメッセージを別のフォーマットのメッセージにマップするために変換を定義できます。変換は、同一の情報を異なるフォーマットで表現するアプリケーションを統合する必要がある場合に有効です。変換はSQL式およびPL/SQLファンクションです。メッセージ変換は、標準JMSインタフェースに対するOracle Streams AQの拡張機能です。

変換は、DBMS_TRANSFORM.create_transformationプロシージャを使用して行います。変換は、次の操作を行う場合に指定できます。

11.9 J2EE準拠

Oracle Database 10gでは、Oracle JMSはSun社のJMS 1.1標準に準拠しています。実行時に、Oracle Java Message Service(OJMS)クライアントに対してJ2EE準拠モードを定義できます。準拠モードにするには、コマンドライン・オプションとしてJavaプロパティ oracle.jms.j2eeCompliantTRUEに設定します。非準拠モードにする場合は何もしません。FALSEがデフォルト値です。

J2EE準拠をサポートし、非準拠モードでも使用できるOracle Streams AQの機能は次のとおりです。