11 Oracle Java Message Serviceの概要
次のトピックでは、Oracle Database Advanced Queuing (AQ)へのOracle Java Message Service (JMS)インタフェースについて説明します。
JMSおよびOracle JMSの一般的な機能
この項の内容は次のとおりです。
JMSコネクションおよびセッション
この項の内容は次のとおりです。
ConnectionFactoryオブジェクト
ConnectionFactory
は、管理者によって定義された接続構成パラメータの集合をカプセル化します。クライアントはこれを使用してJMSプロバイダとの接続を確立します。この場合、Oracle Databaseの一部であるOracle JMSがJMSプロバイダです。
ConnectionFactory
オブジェクトには、次の3種類があります。
-
ConnectionFactory
-
QueueConnectionFactory
-
TopicConnectionFactory
AQjmsFactoryを使用したConnectionFactoryオブジェクトの取得
AQjmsFactory
クラスを使用して、ConnectionFactory
、QueueConnectionFactory
またはTopicConnectionFactory
オブジェクトに対するハンドルを取得できます。
Point-to-Point操作とパブリッシュ・サブスクライブ操作の両方をサポートしているConnectionFactory
を取得するには、AQjmsFactory.getConnectionFactory()
を使用します。QueueConnectionFactory
を取得するには、AQjmsFactory.getQueueConnectionFactory()
を使用します。TopicConnectionFactory
を取得するには、AQjmsFactory.getTopicConnectionFactory()
を使用します。
ConnectionFactory
、QueueConnectionFactory
またはTopicConnectionFactory
は、ホスト名、ポート番号、SIDドライバまたはJDBC URLおよびプロパティを使用して作成できます。
JNDIを使用したConnectionFactoryオブジェクトの検索
JMS管理者は、Lightweight Directory Access Protocol(LDAP)サーバーにConnectionFactory
オブジェクトを登録できます。JMSでJava Naming and Directory Interface(JNDI)の検索を使用可能にするには、次の設定が必要です。
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
インスタンスを使用してJMSSession
を作成します。 -
createQueueSession(true,
0)
このメソッドは
QueueSession
を作成します。 -
createTopicSession(true,
0
)このメソッドは
TopicSession
を作成します。 -
setExceptionListener(ExceptionListener)
このメソッドは、
Connection
の例外リスナーを設定します。問題が非同期でクライアントに通知されます。メッセージを処理するのみのConnection
の場合、その失敗を確認する他の方法はありません。 -
getExceptionListener()
このメソッドは、この
Connection
のExceptionListener
を取得します。
JMSクライアントは、通常1つのConnection
、1つのSession
、複数のMessageProducer
およびMessageConsumer
オブジェクトを作成します。現在のバージョンでは、次の場合を除いて、1つのConnection
につき1つのオープンSession
のみが許可されています。
-
JDBC OCI8ドライバを使用してJMSコネクションを作成する場合
-
ユーザーが、JMSコネクションの作成時に
OracleOCIConnectionPool
インスタンスを提供する場合
Connection
は停止モードで作成されます。この状態では、メッセージを受信できません。通常、設定が完了するまで、Connection
を停止モードにしておきます。その時点でConnection
start()
メソッドがコールされ、メッセージがConnection
コンシューマに配信され始めます。このような設定規則を確立することにより、クライアントが設定されている最中の非同期メッセージ配信の結果、発生するクライアントの混乱を最小限に止められます。
Connection
を起動し、続けて設定を実行できます。これを実行するクライアントは、設定処理中に非同期メッセージの配信処理の準備をする必要があります。MessageProducer
は、Connection
が停止中でもメッセージを送信できます。
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();
などの行を追加するとメッセージを受信できます。
JMS宛先
Destination
は、クライアントがメッセージの送信先および受信元の指定に使用するオブジェクトです。Destination
オブジェクトはQueue
またはTopic
に指定できます。Oracle Database Advanced Queuingでは、特定のデータベースのschema.queue
にマップされます。Queue
は単一コンシューマ・キューに、Topic
はマルチ・コンシューマ・キューにマップします。
JMSセッションを使用したDestinationオブジェクトの取得
Destination
オブジェクトは、Session
オブジェクトからドメイン固有の次のSession
メソッドを使用して作成されます。
-
AQjmsSession.getQueue(queue_owner, queue_name)
このメソッドはJMSキューに対するハンドルを取得します。
-
AQjmsSession.getTopic(topic_owner, topic_name)
このメソッドはJMSトピックに対するハンドルを取得します。
JNDIを使用したDestinationオブジェクトの検索
LDAPサーバーにスキーマ・オブジェクトを登録するようにデータベースを設定できます。データベースがLDAPを使用できるように設定され、GLOBAL_TOPIC_ENABLEDパラメータがTRUEに設定されている場合、すべてのJMSキューおよびトピックは、作成時に自動的にLDAPサーバーに登録されます。管理者は、LDAPに登録されたキューおよびトピックの別名を作成することもできます。LDAPに登録されたキューおよびトピックは、JNDIを介してキューまたはトピックの名前または別名を使用してルックアップできます。
関連項目:
JMS宛先メソッド
Destination
オブジェクトのメソッドには、次のものが含まれます。
-
alter()
このメソッドは
キュー
またはトピック
を変更します。 -
schedulePropagation()
このメソッドは、ソースから宛先への伝播をスケジューリングします。
-
unschedulePropagation()
このメソッドは、スケジュール済伝播のスケジュールを解除します。
-
enablePropagationSchedule()
このメソッドは、伝播スケジュールを有効化します。
-
disablePropagationSchedule()
このメソッドは、伝播スケジュールを無効化します。
-
start()
このメソッドは
キュー
またはトピック
を開始します。キューは、エンキューまたはデキューを可能にするために開始されます。トピックは、パブリッシュまたはサブスクライブを可能にするために開始できます。 -
stop()
このメソッドは
キュー
またはトピック
を停止します。キューは、エンキューまたはデキューを実行不可にするために停止できます。トピックは、パブリッシュまたはサブスクライブを実行不可にするために停止できます。 -
drop()
このメソッドは
キュー
またはトピック
を削除します。
JMSでのシステム・レベルのアクセス制御
Oracle8i以上では、すべてのキューイング操作に対してシステム・レベルのアクセス制御をサポートします。この機能によって、アプリケーション設計者またはDBAは、ユーザーをキュー管理者にできます。キュー管理者は、データベースのどのキューに対してもJMSインタフェース(管理および操作)を起動できます。これによって、データベース上のキュー全体に対するすべての管理スクリプトを1つのスキーマで管理できるため、管理作業が容易になります。
メッセージが宛先キューに届くと、ソース・キューのスキーマ名に基づいたセッションによって、新しく届いたメッセージが宛先キューにエンキューされます。つまり、ソース・キューのスキーマに宛先キューに対するエンキュー権限を付与する必要があります。
リモートの宛先キューに伝播するために、エージェント構造体のアドレス・フィールドのデータベース・リンクに指定されたログイン・ユーザーには、ENQUEUE_ANY
権限を付与するか、または宛先キューに対するエンキュー権限を付与する必要があります。ただし、データベース・リンクのログイン・ユーザーが宛先のキュー表を所有している場合はどのような明示的な権限も付与する必要はありません。
JMSでの宛先レベルのアクセス制御
Oracle8i以上では、エンキューおよびデキュー操作に対してキュー・レベルまたはトピック・レベルのアクセス制御をサポートしています。この機能によって、アプリケーション設計者は、あるスキーマに作成されたキューおよびトピックを他のスキーマで実行中のアプリケーションから保護できます。そのキューまたはトピックが属するスキーマの外で実行しているアプリケーションには、最小限のアクセス権限のみを付与できます。キューまたはトピックに対するアクセス権限として、ENQUEUE
、DEQUEUE
およびALL
がサポートされています。
JMSでの保存およびメッセージ履歴
メッセージは、相互に関連していることがよくあります。たとえば、あるメッセージを処理した結果として他のメッセージが生成された場合、両者は関連付けられています。アプリケーション設計者としては、そのような関連を追跡することが必要な場合があります。Oracle Database Advanced Queuingでは、ユーザーがメッセージをキュー表に保持し、分析のためにSQLで問合せできます。
保存機能およびメッセージ識別子とともに、メッセージ・ジャーナルがOracle Database Advanced Queuingによって自動作成され、追跡ジャーナルまたはイベント・ジャーナルをコールできます。保存、メッセージ識別子およびSQL問合せの協調によって、強力なメッセージ・ウェアハウスを構築できます。
JMSでのOracle Real Application Clustersのサポート
Oracle Database 12cリリース1 (12.1)では、Advanced Queuingに、高性能でスケーラブルなJMSシャード・キューが導入されました。シャード・キューとは、システムで管理されているパーティション化を使用して、独立した複数の物理キューに分割される1つの論理キューです。シャード・キューは、Oracle RACインスタンス全体で使用されるキュー、エンキュー率またはデキュー率の高いキュー、またはサブスクライバの多いキューについて推奨されるJMSキューです。詳細は、「シャード・キューおよびOracle Real Application Clusters (Oracle RAC)」を参照してください。
非シャード・キューの場合は、Oracle Real Application Clusters (Oracle RAC)を使用して、各インスタンスを別々のキューで管理できるようにすることで、Oracle Database Advanced Queuingのパフォーマンスを向上できます。このためには、キューを格納するキュー表に様々なインスタンス・アフィニティ(作業環境)を指定します。これによって、様々なキュー/トピックに対するキュー操作(エンキューまたはデキュー)またはトピック操作(パブリッシュ・サブスクライブ)を並行して行うことができるようになります。
Oracle Database Advanced Queuingのキュー・モニター・プロセスは、キュー表のインスタンス・アフィニティを継続的に監視します。キュー・モニターは指定されたプライマリ・インスタンスが使用可能な場合はそれにキュー表の所有権を割り当て、失敗した場合は指定されたセカンダリ・インスタンスに割り当てます。
キュー表を所有しているインスタンスが終了すると、キュー・モニターはセカンダリ・インスタンスなどの適切なインスタンスに所有者を変更します。
Oracle Database Advanced Queuingの伝播はOracle Real Application Clustersでも使用できますが、これはユーザーに対して透過的です。伝播スケジュールのジョブ・アフィニティは、それぞれのキュー表のアフィニティと同じ値に設定されます。このように、キュー表を所有するインスタンスに対応付けられたjob_queue_process
は、そのキュー表に格納されているキューからの伝播を処理し、ping操作を最小限に抑えます。
JMSでの統計ビューのサポート
各インスタンスは、それぞれのOracle Database Advanced Queuing統計情報をシステム・グローバル領域(SGA)に所有し、他のインスタンスによって収集された統計については認識しません。そのため、インスタンスがGV$AQ
ビューを問い合せると、その他のすべてのインスタンスからそれぞれのその時点の統計情報が問合せ元のインスタンスに集まります。
GV$AQ
ビューは、待機中、準備完了または期限切れの各メッセージ数を必要なときにいつでも問い合せることができます。また、メッセージが処理されるまでの平均待機秒数も表示します。
JMSでの構造化ペイロード/メッセージの型
JMSメッセージは、ヘッダー、プロパティおよび本体で構成されています。
ヘッダーは、クライアントおよびプロバイダの両方でメッセージの識別およびルーティングに使用される値が含まれるヘッダー・フィールドで構成されています。すべてのメッセージは、同じ一連のヘッダー・フィールドをサポートしています。
プロパティは、オプションのヘッダー・フィールドです。JMSによって定義された標準プロパティの他に、プロバイダ固有およびアプリケーション固有のプロパティを含めることもできます。
本体はメッセージ・ペイロードです。JMSは、様々な型のメッセージ・ペイロードおよびJMSで指定されたメッセージ型のJMSメッセージを格納できる型を定義します。
この項の内容は次のとおりです。
JMSメッセージ・ヘッダー
JMSメッセージ・ヘッダーには、次のフィールドが含まれます。
-
JMSDestination
このフィールドには、メッセージの送信先が含まれます。Oracle Database Advanced Queuingでは、これは送信先キューまたはトピックに相当します。
Send
メソッドの完了後にJMSによって設定されるDestination
型です。 -
JMSDeliveryMode
このフィールドは、メッセージのログが記録されるかどうかを決定します。JMSでは、
PERSISTENT
送信(メッセージが決まった記憶域にロギングされる)およびNONPERSISTENT
送信(メッセージがロギングされない)をサポートしています。Send
メソッドの完了後にJMSによって設定されるINTEGER
です。JMSでは、クライアントが指定したJMSDeliveryMode
の値をオーバーライドするよう管理者がJMSを構成することが可能です。 -
JMSMessageID
このフィールドは、プロバイダ内のメッセージを一意に識別します。すべてのメッセージIDは先頭に文字列
ID:
を使用する必要があります。Send
メソッドの完了後にJMSによって設定されるString
型です。 -
JMSTimeStamp
このフィールドには、送信先のプロバイダにメッセージが渡された時間が含まれます。Oracle Database Advanced Queuingのメッセージのエンキュー時間にマッピングされます。
Send
メソッドの完了後にJMSによって設定されるLong
型です。 -
JMSCorrelationID
このフィールドは、クライアントがメッセージを別のメッセージにリンクするために使用できます。JMSクライアントによって設定される
String
型です。 -
JMSReplyTo
このフィールドには、メッセージ送信時にクライアントが指定する
Destination
型が含まれます。クライアントはoracle.jms.AQjmsAgent
、javax.jms.Queue
またはjavax.jms.Topic
を使用できます。 -
JMSType
このフィールドには、送信時にクライアントが指定するメッセージ・タイプの識別子が含まれます。これは
String
型です。移植性を高めるために、JMSType
に記号値を使用することをお薦めします。 -
JMSExpiration
このフィールドは、非Java EE準拠モードでは、エンキュー時間と
TimeToLive
の合計です。準拠モードでは、デキューされたメッセージのJMSExpiration
ヘッダー値は、メッセージのエンキュー時のJMSTimeStamp
(ミリ秒単位のグリニッジ標準時)とTimeToLive
(ミリ秒単位)の合計です。Send
メソッドの完了後にJMSによって設定されるLong
型です。JMSでは、クライアントが指定したJMSExpiration
の値をオーバーライドするよう管理者がJMSを構成することが可能です。 -
JMSPriority
このフィールドには、メッセージの優先度が含まれます。
Send
メソッドの完了後にJMSによって設定されるINTEGER
です。Java EE準拠モードでは、優先度に使用できる値は0
から9
で、9
の優先度が最も高く、4
がデフォルトで、Sun Microsystem JMS 1.1標準に準拠しています。デフォルトは非準拠モードです。JMSでは、クライアントが指定したJMSPriority
の値をオーバーライドするよう管理者がJMSを構成することが可能です。 -
JMSRedelivered
このフィールドは、JMSプロバイダによって設定されたブールです。
関連項目:
JMSメッセージ・プロパティ
JMSプロパティは、クライアントによって明示的に設定されるか、またはJMSプロバイダによって自動的に設定されます(通常、これらは読取り専用です)。JMSプロパティには、Send
およびReceive
操作に指定されたパラメータを使用して設定されるものもあります。
プロパティで、メッセージにオプションのヘッダー・フィールドを追加できます。プロパティによって、クライアントは、messageSelector
を使用して、クライアントのかわりにJMSプロバイダにアプリケーション固有基準を使用してメッセージを選択させることができます。プロパティ名は文字列で、値はBoolean
、byte
、short
、int
、long
、float
、double
および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
このフィールドは、プロバイダによって設定されたメッセージ状態です。メッセージ状態は、
WAITING
、READY
、EXPIRED
またはRETAINED
です。
Oracle固有のJMSプロパティは、すべてJMS_Oracle
で始まります。次のものがあります。
-
JMS_OracleExcpQ
このフィールドは、元の宛先に配信できないメッセージを送信するキュー名です。JMSクライアントによって設定される
String
型です。EXCEPTION
タイプの宛先のみをJMS_OracleExcpQ
プロパティで指定できます。 -
JMS_OracleDelay
このフィールドは、メッセージの配信を遅延する時間(秒単位)です。JMSクライアントによって設定される
Integer
型です。これは、メッセージの配信順序に影響を与える可能性があります。 -
JMS_OracleOriginalMessageId
このフィールドは、メッセージがある宛先から別の宛先に伝播された場合に、ソースのメッセージのメッセージ識別子に設定されます。JMSプロバイダによって設定される
String
型です。メッセージが伝播されていない場合、このプロパティはJMSMessageId
と同じ値です。
クライアントは、プロパティを定義することによって、メッセージにヘッダー・フィールドを追加できます。これらのプロパティをmessageSelector
で使用して特定のメッセージを選択できます。
JMSメッセージ本体
JMSでは、次の5つのフォーマットのメッセージ本体が提供されます。
StreamMessage
StreamMessage
オブジェクトは、Javaプリミティブのストリームの送信に使用されます。格納と読取りは順次的に行われます。これはMessage
から継承し、StreamMessage
本文を追加します。メソッドは主にjava.io.DataInputStream
とjava.io.DataOutputStream
のメソッドに基づいています。
基本データ型の値は、それぞれの型のメソッドを使用して、明示的に読込みまたは書込みできます。抽象的なオブジェクトとして読込みまたは書込みすることもできます。StreamMessage
オブジェクトを使用するには、SYS.AQ$_JMS_STREAM_MESSAGE
またはAQ$_JMS_MESSAGE
ペイロード型を持つキュー表を作成します。
StreamMessage
オブジェクトは、表11-1に示す変換をサポートします。行の型として書き込まれる値は、列の型として読み込むことができます。
表11-1 StreamMessageの変換
入力 | Boolean | byte | short | char | int | long | float | double | String | byte[] |
---|---|---|---|---|---|---|---|---|---|---|
|
X |
- |
- |
- |
- |
- |
- |
- |
X |
- |
|
- |
X |
X |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
X |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
- |
X |
- |
- |
- |
- |
X |
- |
|
- |
- |
- |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
- |
- |
- |
X |
- |
- |
X |
- |
|
- |
- |
- |
- |
- |
- |
X |
X |
X |
- |
|
- |
- |
- |
- |
- |
- |
- |
X |
X |
- |
|
X |
X |
X |
X |
X |
X |
X |
X |
X |
- |
|
- |
- |
- |
- |
- |
- |
- |
- |
- |
X |
BytesMessage
BytesMessage
オブジェクトは、1つの未解釈バイトのストリームを含むメッセージを送信する場合に使用します。これはMessage
から継承し、BytesMessage
本文を追加します。メッセージの受信者が、そのバイト列を解析します。メソッドは主にjava.io.DataInputStream
とjava.io.DataOutputStream
のメソッドに基づいています。
これは、クライアントが既存のメッセージ・フォーマットをコード化するためのメッセージ型です。可能であれば、かわりに他の自己定義メッセージ型を使用してください。
基本データ型の値は、それぞれの型のメソッドを使用して、明示的に書込みができます。また、抽象的なオブジェクトとして書き込むこともできます。BytesMessage
オブジェクトを使用するには、SYS.AQ$_JMS_BYTES_MESSAGE
またはAQ$_JMS_MESSAGE
ペイロード型を持つキュー表を作成します。
MapMessage
MapMessage
オブジェクトは、名前がString
型で値がJava基本データ型である名前/値ペアの集合を送信する場合に使用します。このエントリには、名前を指定して順次的またはランダムにアクセスできます。エントリの順序は定義されません。これはMessage
から継承し、MapMessage
本文を追加します。基本データ型の値は、それぞれの型のメソッドを使用して、明示的に読込みまたは書込みできます。抽象的なオブジェクトとして読込みまたは書込みすることもできます。
MapMessage
オブジェクトを使用するには、SYS.AQ$_JMS_MAP_MESSAGE
またはAQ$_JMS_MESSAGE
ペイロード型を持つキュー表を作成します。MapMessage
オブジェクトは、表11-2に示す変換をサポートします。この表の「X」は、行の型として書き込まれる値を列の型として読み取ることができることを意味します。
表11-2 MapMessageの変換
入力 | Boolean | byte | short | char | int | long | float | double | String | byte[] |
---|---|---|---|---|---|---|---|---|---|---|
|
X |
- |
- |
- |
- |
- |
- |
- |
X |
- |
|
- |
X |
X |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
X |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
- |
X |
- |
- |
- |
- |
X |
- |
|
- |
- |
- |
- |
X |
X |
- |
- |
X |
- |
|
- |
- |
- |
- |
- |
X |
- |
- |
X |
- |
|
- |
- |
- |
- |
- |
- |
X |
X |
X |
- |
|
- |
- |
- |
- |
- |
- |
- |
X |
X |
- |
|
X |
X |
X |
X |
X |
X |
X |
X |
X |
- |
|
- |
- |
- |
- |
- |
- |
- |
- |
- |
X |
TextMessage
TextMessage
オブジェクトは、java.lang.StringBuffer
を含むメッセージを送信する場合に使用します。これはMessage
から継承し、TextMessage
本文を追加します。テキスト情報は、getText()
およびsetText(
...)
メソッドを使用して読込みまたは書込みができます。TextMessage
オブジェクトを使用するには、SYS.AQ$_JMS_TEXT_MESSAGE
またはAQ$_JMS_MESSAGE
ペイロード型を持つキュー表を作成します。
ObjectMessage
ObjectMessage
オブジェクトは、シリアライズ可能なJavaオブジェクトを含むメッセージを送信する場合に使用します。これはMessageから継承し、単一のJava参照を含む本文を追加します。シリアライズ可能なJavaオブジェクトのみ使用できます。Javaオブジェクトのコレクションを送信する必要がある場合、JDK 1.4で提供されているコレクション・クラスのいずれかを使用できます。オブジェクトは、getObject()
メソッドおよびsetObject(
...)
メソッドを使用して読込みまたは書込みできます。ObjectMessage
オブジェクトを使用する場合、SYS.AQ$_JMS_OBJECT_MESSAGE
またはAQ$_JMS_MESSAGE
ペイロード型でキュー表を作成します。
AdtMessage
AdtMessage
オブジェクトは、Oracleのオブジェクト型に対応するJavaオブジェクトを含むメッセージを送信する場合に使用します。これらのオブジェクトはMessage
から継承され、CustomDatum
またはORAData
インタフェースを実装するJavaオブジェクトを含む本体を追加します。
AdtMessage
オブジェクトを使用するには、Oracleのオブジェクト型としてのペイロード型を持つキュー表を作成します。AdtMessage
のペイロードは、getAdtPayload
およびsetAdtPayload
メソッドを使用して、読取りおよび書込みができます。
AdtMessage
オブジェクトを使用してSYS.XMLType
型のキューへメッセージを送信することもできます。oracle.xdb.XMLType
クラスを使用してメッセージを作成する必要があります。
AdtMessage
オブジェクトの場合、クライアントが次を取得できます。
-
JMSXDeliveryCount
-
JMSXRecvTimeStamp
-
JMSXState
-
JMS_OracleExcpQ
-
JMS_OracleDelay
関連項目:
CustomDatum
インタフェースおよびORAData
インタフェースの詳細は、『Oracle Database Java開発者ガイド』を参照してください。
異なるメッセージ型でのメッセージ・プロパティの使用
次のメッセージ・プロパティは、クライアントがsetProperty
コールを使用して設定できます。StreamMessage
、BytesMessage
、ObjectMessage
、TextMessage
およびMapMessage
オブジェクトの場合、クライアントによって次の設定ができます。
-
JMSXAppID
-
JMSXGroupID
-
JMSXGroupSeq
-
JMS_OracleExcpQ
-
JMS_OracleDelay
AdtMessage
オブジェクトの場合、クライアントによって次の設定ができます。
-
JMS_OracleExcpQ
-
JMS_OracleDelay
次のメッセージ・プロパティは、クライアントがgetProperty
コールを使用して取得できます。StreamMessage
、BytesMessage
、ObjectMessage
、TextMessage
およびMapMessage
オブジェクトの場合、クライアントが次を取得できます。
-
JMSXuserID
-
JMSXAppID
-
JMSXDeliveryCount
-
JMSXGroupID
-
JMSXGroupSeq
-
JMSXRecvTimeStamp
-
JMSXState
-
JMS_OracleExcpQ
-
JMS_OracleDelay
-
JMS_OracleOriginalMessageID
Oracle JMSを使用したバッファ済メッセージ
メッセージの送信時にdeliveryMode
としてNON_PERSISTENT
を指定すると、非永続JMSメッセージを送信できます。JMS非永続メッセージは決まった記憶域に記録する必要がないため、JMSシステム障害が発生すると消失する可能性があります。JMS非永続メッセージはOracle Database Advanced Queuingで使用可能なバッファ済メッセージに類似していますが、両者には重要な相違点も存在します。
注意:
Oracle JMSの非永続メッセージを、Oracle Database 10gリリース2(10.2)で非推奨になったOracle Database Advanced Queuingの非永続キューと混同しないでください。
関連項目:
トランザクションのコミットとクライアントの確認
JMSのdeliveryMode
は、メッセージのトランザクション属性と直交します。JMS非永続メッセージは、処理済セッションまたは非処理済セッションで送受信できます。JMS非永続メッセージを処理済セッションで送受信する場合、JMS操作の効果は処理済セッションのコミット後にのみ参照可能です。CLIENT_ACKNOWLEDGE
確認モードの非処理済セッションで受信する場合、このメッセージの受信による効果は、クライアントがメッセージを確認した後にのみ参照可能です。確認されない場合、メッセージは削除されず、クライアントがSession.recover
をコールすると再配信されます。
これに対して、Oracle Database Advanced Queuingのバッファ済メッセージでは、このようなトランザクションまたは確認の概念はサポートされません。バッファ済メッセージの送受信は、どちらもIMMEDIATE
可視性モードで実行する必要があります。したがって、セッションがコミットされたかどうかやメッセージが確認されたかどうかは関係なく、ユーザーは送受信操作の効果を即時に参照できます。
各種API
通常のJMS送信およびパブリッシュ・メソッドで送信されるメッセージは、Oracle Database Advanced Queuingでは永続メッセージとして扱われます。通常のJMS受信メソッドは、AQ永続メッセージのみを受信します。バッファ済メッセージを送受信するには、Oracle拡張APIであるbufferSend
、bufferPublish
およびbufferReceive
を使用する必要があります。
関連項目:
bufferSend
、bufferPublish
およびbufferReceive
の詳細は、Oracle Databaseアドバンスト・キューイングJava APIリファレンスを参照してください
ペイロード制限
バッファ済メッセージのOracle Database Advanced Queuing実装では、LOB
属性はサポートされていません。このため、5種類の標準JMSメッセージのペイロードには次の制限が適用されます。
-
JMS
TextMessage
のペイロードは4000バイト以内です。Oracle JMSのキャラクタ・セット変換時には、テキスト・ペイロードをデータベースに格納するために
VARCHAR
のかわりにCLOB
を使用するように控え目な選択が必要になる場合があるため、データベース・キャラクタ・セットによってはこの上限値がさらに低くなる場合があります。 -
JMS
BytesMessage
のペイロードは2000バイト以内です。 -
JavaでシリアライズされたJMS
ObjectMessage
、StreamMessage
およびMapMessage
データは、2000バイト以内である必要があります。 -
他のすべてのOracle JMS ADTメッセージの場合、対応するOracleデータベースADTに
LOB
属性を含めることはできません。
各種定数
表11-3に示すように、Oracle Database Advanced QueuingとOracle JMSのAPIでは、バッファ済メッセージと永続メッセージの指定に使用される数値が異なります。
表11-3 Oracle Database AQとOracle JMSのバッファ済メッセージ定数
API | 永続メッセージ | バッファ済メッセージ |
---|---|---|
Oracle Database Advanced Queuing |
|
|
Oracle JMS |
|
|
JMSのバッファ済メッセージ
バッファ済メッセージでは、JMSメッセージ標準が完全にサポートされています。Oracle JMSでは、それらの標準がいくつかの方法で拡張されています。
関連項目:
JMSバッファ済メッセージのエンキュー
Oracle JMSでは、永続メッセージおよびバッファ済メッセージを同じJMSキュー/トピックにエンキューできるように、個別のメッセージにJMSDeliveryMode
を設定することによって、アプリケーションはバッファ済メッセージを送信できます。
Oracle JMSのバッファ済メッセージは、エンキュー時刻、優先順位またはその両方で順序付けできます。順序付けは異なるメッセージ・タイプ間では適用されません。このため、たとえば、後に送信された永続メッセージが前に送信されたバッファ済メッセージより前に配信されることがあります。Oracle JMSのバッファ済メッセージでは、期限切れもサポートされます。
関連項目:
JMSバッファ済メッセージのデキュー
JMSでは、JMSサブスクライバが両方のメッセージ・タイプを対象にできるように、サブスクライバが永続メッセージのみまたはバッファ済メッセージのみを対象とするように宣言することを要求しません。
Oracle JMSは、JMSMessageID
による高速で効率的なメッセージのデキュー、メッセージ・ヘッダーのセレクタ、およびメッセージ・プロパティのセレクタをサポートしています。Oracle JMSデキュー・コールは、永続メッセージとバッファ済メッセージの両方をチェックします。
注意:
Oracle JMS永続メッセージには一意のメッセージ識別子があります。Oracle JMSバッファ済メッセージ識別子は、キュー/トピック内でのみ一意です。
同時デキュー・プロセスが同じサブスクライバの同じキューからデキューしている場合は、他のプロセスによってロックされているメッセージがスキップされます。
関連項目:
トランザクションのサポート
バッファ済メッセージがトランザクション・セッションでエンキューされる場合、JMSではそれらに対するトランザクション・サポートが必要となります。Oracle JMSでは、バッファ済メッセージに関連するトランザクション・セッションで次の標準が満たされることが保証されます。
-
原子性
Oracle JMSトランザクション内の永続メッセージおよびバッファ済メッセージは、アトミックにコミットまたはロールバックされます。バッファ済メッセージがディスクに書き込まれた場合(LOBに関連するメッセージの場合など)でも、ロールバックによってそれらが削除されます。
-
一貫性
永続メッセージ操作およびバッファ済メッセージ操作がトランザクションでインターリーブされる場合、すべてのOracle JMSユーザーは影響を受けるキュー/トピックの一貫性のあるビューを共有します。トランザクションによってエンキューされたすべての永続メッセージおよびバッファ済メッセージは、コミット時に表示できるようになります。プロセスがトランザクションの途中で終了した場合は、永続メッセージおよびバッファ済メッセージの両方が元に戻されます。Oracle JMSユーザーには、トランザクションのすべての永続メッセージおよびバッファ済メッセージが表示されるか、それらのいずれも表示されません。
-
分離
トランザクションのバッファ済エンキュー操作は、トランザクションがコミットされるまではオーナー・トランザクションにのみ表示されます。トランザクションがコミットされると、すべてのコンシューマに表示されます。
デキュー・トランザクションによってロックされているメッセージはブラウズできます。
確認メッセージの受信
非トランザクション・セッションの確認メッセージ受信のためのack_mode
パラメータには、3つの値が定義されています。
-
DUPS_OK_ACKNOWLEDGE
このモードでは、重複メッセージが許可されます。
-
AUTO_ACKNOWLEDGE
このモードでは、セッションはメッセージを自動的に確認します。
-
CLIENT_ACKNOWLEDGE
このモードでは、メッセージ・プロデューサ確認メソッドをコールすることによって、クライアントはメッセージを明示的に確認します。メッセージを確認すると、以前に処理されたすべてのメッセージが確認されます。
関連項目:
バッファ済メッセージのサービス品質
JMSは、伝播されていないバッファ済メッセージを最大1回配信することをサポートするようにプロバイダに要求しています。バッファ済メッセージのリカバリが無効にされている場合、Oracle JMSはこの標準を満たしています。
現在のメッセージ伝播の実装では、メッセージの重複配信が行われることがあります。ただし、メッセージの伝播はOracle JMSによって提供される拡張であるため、これはJMS標準に違反しません。
関連項目:
バッファ済メッセージが重複配信される原因については、バッファ済メッセージの伝播を参照してください。
バッファ済メッセージでサポートされるJMSタイプ
Oracle JMSは、JMSで定義されているタイプをOracleのユーザー定義タイプにマップし、JMSメッセージを格納するためにそれらのユーザー定義タイプのキューを作成します。これらのタイプの一部にはLOB属性があり、メッセージが永続またはバッファ済のいずれであってもOracle JMSはディスクに書き込みます。
たとえば、JMSタイプJMSTextMessage
のユーザー定義タイプSYS.AQ$_JMS_TEXT_MESSAGE
では、4kより小さいテキスト文字列がVARCHAR2
列に格納されます。ただし、4kより大きいテキスト文字列を格納するためのCLOB属性があります。
JMSメッセージは4kより大きい場合がよくあるため、Oracle JMSは大きいメッセージをメモリーに格納できる新しいADTを提供しています。ADTのディスク表示は変わりませんが、いくつかのVARCHAR2
/RAW
属性では最大100kのサイズのJMSメッセージをメモリーに格納できます。100kより大きいメッセージもバッファ済メッセージとしてパブリッシュできますが、ディスクに書き込まれます。
関連項目:
JMS Point-to-Pointモデル機能
Point-to-Pointモデルでは、クライアントは、1つのポイントから別のポイントへメッセージを交換します。メッセージのプロデューサとコンシューマは、シングル・コンシューマ・キューを使用してメッセージを送受信します。管理者は、AQjmsSession
のcreateQueue
メソッドを使用して、シングル・コンシューマ・キューを作成します。キューを使用する前に、AQjmsDestination
でstart
コールを使用して、キューをエンキュー/デキューに対して有効にする必要があります。クライアントは、AQjmsSession
のgetQueue
メソッドを使用して事前に作成されたキューに対するハンドルを取得します。
シングル・コンシューマ・キューの場合、メッセージは1つのコンシューマが1度のみ処理できます。同じキューから同時にデキューするプロセスまたはオペレーティング・システム・スレッドが複数存在する場合、各プロセスはキューの先頭にあるロックされていない最初のメッセージをデキューします。ロックを作成したプロセス以外のプロセスは、ロックされたメッセージをデキューできません。
処理が済むと、キューの保存期間が0(ゼロ)の場合はそのメッセージは削除され、そうでない場合は指定された期間保存されます。メッセージが保存されている間は、キュー表ビューに対してSQLを使用して問い合せたり、QueueBrowser
で処理済メッセージのメッセージ識別子を指定してデキューできます。
QueueSender
クライアントは、QueueSender
を使用して、キューにメッセージを送信します。これは、クライアントのSession
でキューをcreateSender
メソッドに渡すことによって作成されます。また、クライアントにはキューを指定しないで、QueueSender
を作成するオプションがあります。この場合、キューを送信操作のたびに指定する必要があります。
クライアントは、QueueSender
によって送信されたすべてのメッセージのデフォルト配信モード、優先順位およびTimeToLive
を指定できます。または、クライアントはこれらのオプションを各メッセージに対して定義できます。
QueueReceiver
クライアントはQueueReceiver
を使用してキューからメッセージを受信します。これは、クライアントのSession
でcreateQueueReceiver
を使用して作成されます。messageSelector
があってもなくても作成できます。
QueueBrowser
QueueBrowser
を使用すると、クライアントはメッセージを削除しないで、キュー上でメッセージを参照できます。このブラウズ用メソッドは、キュー内のメッセージをスキャンするために使用されるjava
.util
.Enumeration
を戻します。nextElement
に対する最初のコールが、キューのスナップショットを取得します。QueueBrowser
は、messageSelector
を使用して作成しても、使用せずに作成してもかまいません。
QueueBrowser
も、メッセージをスキャン中にオプションでロックできます。これは、メッセージに対するSELECT
...for
UPDATE
コマンドの場合と似ています。これによって、他のコンシューマがスキャン中のメッセージを削除することはなくなります。
MessageSelector
messageSelector
によって、クライアントは、コンシューマに配信されるメッセージをmessageSelector
式と一致するメッセージに制限できるようになります。TextMessage
型、StreamMessage
型、BytesMessage
型、ObjectMessage
型またはMapMessage
型のペイロードを含むキューのmessageSelector
には、次の1つ以上を持つ任意の式を含めることができます。
-
接頭辞「ID:」が付いたJMSメッセージ識別子
JMSMessageID ='ID:23452345'
-
JMSメッセージ・ヘッダー・フィールドまたはプロパティ
JMSPriority < 3 AND JMSCorrelationID = 'Fiction' JMSCorrelationID LIKE 'RE%'
-
ユーザー定義のメッセージ・プロパティ
color IN ('RED', BLUE', 'GREEN') AND price < 30000
AdtMessage
型のペイロードを含むキューのmessageSelector
には、次の1つ以上を持つ任意の式を含めることができます。
-
接頭辞「ID:」なしのメッセージ識別子
msgid = '23434556566767676'
-
優先順位または相関識別子、あるいはその両方
priority < 3 AND corrid = 'Fiction'
-
メッセージ・ペイロード
tab.user_data.color = 'GREEN' AND tab.user_data.price < 30000
JMSパブリッシュ・サブスクライブ・モデル機能
この項の内容は次のとおりです。
JMSパブリッシュ・サブスクライブの概要
JMSでは、パブリッシャ(出版者)の機能を持つアプリケーションとサブスクライバ(購読者)の役割を果すアプリケーションとの間の柔軟で動的な通信が可能です。アプリケーションが結合されることはなく、メッセージとその内容に基づいて相互に作用します。
メッセージの配信では、パブリッシャ・アプリケーションが明示的にメッセージ受信者を処理または管理する必要はありません。このため、パブリッシャ・アプリケーションの論理を変更しなくても、新しいサブスクライバ・アプリケーションを動的に追加できます。
同様にサブスクライバ・アプリケーションは、メッセージを送信しているパブリッシャ・アプリケーションに関係なく、メッセージの内容に基づいてメッセージを受信します。このため、サブスクライバ・アプリケーションの論理を変更しなくても、新しいパブリッシャ・アプリケーションを動的に追加できます。
サブスクライバ・アプリケーションは、メッセージ・プロパティまたはトピックのメッセージ内容に対してルールベースのサブスクリプション(予約購読)を定義することで、どのようなメッセージに関心があるのかを指定できます。システムは、ルールベースのサブスクリプションを使用して、パブリッシュされたメッセージの受信者を計算し、自動的にルーティングします。
パブリッシュ・サブスクライブ・モデルでは、メッセージはトピックに対してパブリッシュされ、トピックから受信されます。トピックは、AQjmsSession
のCreateTopic()
メソッドを使用して作成されます。クライアントは、AQjmsSession
のgetTopic()
メソッドを使用して事前に作成されたトピックに対するハンドルを取得できます。
DurableSubscriber
クライアントはDurableSubscriber
を、クライアントのSession
内でcreateDurableSubscriber()
メソッドを使用して作成します。messageSelector
があってもなくても作成できます。
messageSelector
によって、クライアントは、サブスクライバに配信されるメッセージをセレクタにマッチするメッセージに制限できます。セレクタ構文の詳細は、Oracle Databaseアドバンスト・キューイングJava APIリファレンスのcreateDurableSubscriber
に関する項を参照してください。
永続サブスクライバが同じ名前を使用するときのアクションは、実行時にOracle Java Message Service (Oracle JMS)クライアントに設定されるJava EE準拠モードによって異なります。
非準拠モードでは、同じ名前の2つの永続的なTopicSubscriber
オブジェクトが、2つの異なるトピックに対してアクティブになることができます。準拠モードでは、複数の永続サブスクライバが同じ名前を持つことは許可されません。同じトピックに対して作成された2つのサブスクライバが同じ名前を使用する場合、各サブスクライバに使用されるセレクタが異なると、DBMS_AQJMS.ALTER_SUBSCRIBER()
の内部コールを使用して、基になるOracle Database Advanced Queuingサブスクリプションが変更されます。
2つのサブスクライバが同じ名前を使用し、2つの異なるトピックに対して作成される場合、同じサブスクリプション名を使用するクライアントがそれぞれサブスクリプション名を作成すると、既存のサブスクリプションは削除され新しいサブスクリプションが作成されます。
2つのサブスクライバが同じ名前を使用し、2つの異なるトピックに対して作成される場合、別のクライアント(最初にそのサブスクリプション名を作成したクライアントではない)が既存のサブスクリプション名を使用すると、サブスクリプションは削除されずにエラーが発生します。サブスクリプションがJMSまたはPL/SQLのどちらで作成されたかが不明であるため、その他のトピックについてのサブスクリプションは削除しないでください。
関連項目:
RemoteSubscriber
リモート・サブスクライバは、createRemoteSubscriber
コールを使用して定義されます。リモート・サブスクライバは、リモート・トピックでの特定のコンシューマ、またはリモート・トピックでのすべてのサブスクライバになることができます。
リモート・サブスクライバは、AQjmsAgent
構造を使用して定義されます。AQjmsAgent
は、名前およびアドレスで構成されます。名前は、リモート・トピックのconsumer_name
を参照します。アドレスは、次のようにしてリモート・トピックを参照します。
schema.topic_name[@dblink]
リモート・トピックで特定のコンシューマに対してメッセージをパブリッシュするには、リモート・トピックでの受信者のsubscription_name
が、AQjmsAgent
の名前フィールドに指定されている必要があります。リモート・トピックは、AQjmsAgent
のaddressフィールドに指定される必要があります。
リモート・トピックのすべてのサブスクライバに対してメッセージをパブリッシュするには、AQjmsAgent
のnameフィールドをNULLに設定する必要があります。リモート・トピックは、AQjmsAgent
のaddressフィールドに指定される必要があります。
TopicPublisher
メッセージはTopicPublisher
を使用してパブリッシュされます。これは、Topic
をcreatePublisher
メソッドに渡すことによって作成されます。また、クライアントにはTopic
を指定しないで、TopicPublisher
を作成するオプションがあります。この場合、Topic
をパブリッシュ操作のたびに指定する必要があります。クライアントは、TopicPublisher
によって送信されるすべてのメッセージのデフォルト配信モード、優先順位およびTimeToLive
を指定できます。また、各メッセージごとに、これらのオプションを指定することもできます。
受信者リスト
JMSパブリッシュ・サブスクライブ・モデルでは、クライアントは、トピックのすべてのサブスクライバにメッセージを送信するのではなく、明示的な受信者リストを指定できます。これらの受信者は、トピックの既存のサブスクライバである場合もあれば、そうでない場合もあります。受信者リストは、このメッセージのトピックのサブスクリプション・リストをオーバーライドします。受信者リスト機能は、JMSに対するOracleの拡張です。
TopicReceiver
受信者名が受信者リストに明示的に指定されていても、その受信者がキューのサブスクライバではない場合、その受信者に送信されるメッセージは、TopicReceiver
を作成することによって受信できます。サブスクライバ名が指定されていない場合、クライアントがメッセージを受信するには、リモート・サイトで永続サブスクライバを使用する必要があります。TopicReceiver
は、JMSに対するOracleの拡張です。
TopicReceiver
は、messageSelector
を使用して作成できます。これによって、クライアントは、受信者に配信されるメッセージをセレクタにマッチするメッセージに制限できます。
関連項目:
TopicBrowser
TopicBrowser
を使用すると、クライアントはメッセージを削除しないでトピック上でメッセージを参照できます。このブラウズ用メソッドは、トピック・メッセージをスキャンするために使用されるjava.util.Enumeration
を戻します。TopicBrowser
を作成できるのは、永続サブスクライバのみです。nextElement
に対する最初のコールが、トピックのスナップショットを取得します。
TopicBrowser
は、メッセージをスキャン中にオプションでロックできます。これは、メッセージに対するSELECT
...for
UPDATE
コマンドの場合と類似しています。これによって、他のコンシューマがスキャン中のメッセージを削除することはなくなります。
TopicBrowser
は、messageSelector
を使用して作成できます。これによって、クライアントは、コンシューマに配信されるメッセージをセレクタにマッチするメッセージに制限できるようになります。
TopicBrowser
は、パージ機能をサポートしています。これによって、TopicBrowser
を使用するクライアントは、トピックの現行のブラウズ操作中に参照されたすべてのメッセージを廃棄できます。パージとは、参照済のすべてのメッセージを破壊的に受信することと同じです(TopicSubscriber
を使用して削除した場合と似ています)。
パージでは、メッセージがTopicBrowser
のjava.lang.Enumeration
のnextElement()
操作へのコールを使用してクライアントに戻された場合、そのメッセージは参照済とみなされます。クライアントがまだ参照していないメッセージは、パージ中には廃棄されません。パージ操作は、同じTopicBrowser
に対して何度も実行できます。
TopicBrowser
の作成に使用したJMS Session
がコミットされると、パージは正常に実行されます。セッションに対する操作がロールバックされた場合、パージ操作も取り消されます。
JMSメッセージ・プロデューサの機能
メッセージの優先順位および順序付け
メッセージの順序付けは、メッセージがキューまたはトピックから受信される順序を決定します。キューまたはトピックのキュー表の作成時に順序づけの方式が指定されます。現在は、Oracle Database Advanced Queuingでは、メッセージの優先順位とエンキュー時間に基づいた順序づけをサポートしており、これによって順序づけの方法が4種類あります。
-
First-In, First-Out (FIFO)
エンキュー時刻が順序付け基準として選択されると、メッセージはエンキュー時刻の順序で受信されます。エンキュー時刻は、メッセージのパブリッシュ/送信時にOracle Database Advanced Queuingによってメッセージに割り当てられます。これはデフォルトの順序付けです。
-
優先順位による順序付け
優先順位による順序付けが選択されると、各メッセージに優先順位が割り当てられます。優先順位は、パブリッシュ/送信時に
メッセージ・プロデューサ
によってメッセージ・プロパティとして指定できます。メッセージは、割り当てられた優先順位の順序で受信されます。 -
FIFO優先順位
FIFO優先順位による順序付けが選択されると、トピックまたはキューは優先順位による順序付けの場合と同様に機能します。2つのメッセージに同じ優先順位が割り当てられた場合、両者はエンキュー時刻の順に受信されます。
-
エンキュー時刻に続く優先順位による順序付け
同じエンキュー時刻のメッセージは、そのメッセージの優先順位に従って受信されます。2つのメッセージの順序付け基準が同じ場合、受信される順序は予想できません。ただし、1つのセッション中に特定の順序付け基準で生成されたメッセージは、送信された順序で受信されることがOracle Database Advanced Queuingにより保証されます。
永続メッセージに使用できる順序付けスキームはすべて、バッファ済メッセージにも使用できますが、使用できるのは各メッセージ・クラス内のみです。同じセッション内でエンキューまたはパブリッシュされた永続メッセージとバッファ済メッセージ間の順序付けは、現在はサポートされていません。
メッセージ遅延の指定
メッセージをキュー/トピックに対して送信/パブリッシュするときに、遅延を指定できます。遅延は、そのメッセージがメッセージ・コンシューマに対して使用可能になるまでの時間を表します。遅延指定されたメッセージは、遅延の期限が切れるまで待機状態になります。遅延指定は、メッセージ識別子による受信でオーバーライドされます。
遅延は、JMSメッセージ・プロパティに対するOracle Database Advanced Queuingの拡張機能です。Oracle Database Advanced Queuingのバックグラウンド・プロセスのキュー・モニターが起動される必要があります。
メッセージ期限切れの指定
メッセージのプロデューサは、メッセージの期限切れまたはTimeToLive
を指定できます。これによって、そのメッセージがメッセージ・コンシューマに対して使用可能な期間が定義されます。
TimeToLive
は、送信/パブリッシュ時に指定するか、MessageProducer
の設定済TimeToLive
メソッドを使用して指定することが可能で、前者が後者よりも優先されます。TimeToLive
を実装するには、Oracle Database Advanced Queuingのバックグラウンド・プロセスのキュー・モニターが実行されている必要があります。
メッセージのグループ化
1つのキューまたはトピックに属するメッセージをグループ化してセットを形成し、一度に1人のユーザーのみによって消費されるように設定できます。そのためには、トランザクション処理によるメッセージのグループ化が可能なキュー表にキューまたはトピックを作成する必要があります。同じグループに属するメッセージはすべて同じトランザクション内に作成する必要があり、同じトランザクション内に作成されたメッセージはすべて同じグループに属します。
メッセージのグループ化は、JMS仕様に対するOracle Database Advanced Queuingの拡張機能です。
この機能を使用すると、複雑なメッセージを、リンクされた一連の単純なメッセージに分割できます。たとえば、請求書キュー宛ての請求書は、ヘッダーのメッセージ、詳細情報の複数のメッセージ、フッターのメッセージの順に分割できます。
小さいオブジェクトに分割できるイメージやビデオなどの複合ラージ・オブジェクトがメッセージ・ペイロードにある場合は、メッセージのグループ化が非常に有効です。
グループに含まれるメッセージの優先順位、遅延および期限切れの各プロパティは、単にグループの最初のメッセージ(ヘッダー)のプロパティによってのみ判断されます。グループの他のメッセージのプロパティは無視されます。
メッセージ・グループは、伝播中も保持されます。宛先トピックは、トランザクション処理のグループ化に対して使用可能にしておく必要があります。
関連項目:
トランザクション処理でグループ化可能なキューからメッセージをデキューするときにメッセージ・グループを保持する場合、注意する必要がある制限については、「デキュー機能」を参照してください。
JMSメッセージ・コンシューマ機能
この項の内容は次のとおりです。
メッセージの受信
JMSアプリケーションは、メッセージ・コンシューマを作成することによって、メッセージを受信できます。メッセージは、receive
コールを使用して同期的に受信するか、メッセージ・リスナーを使用して非同期的に受信できます。
受信モードには次の3つがあります。
-
メッセージがコンシューマに届くまでブロック
-
指定最大時間までブロック
-
非ブロック
受信におけるメッセージのナビゲーション
コンシューマがナビゲーション・モードを指定しない場合、セッションの最初のreceive
はキューまたはトピックの最初のメッセージを取り出し、第2のreceive
は次のメッセージを取得します。優先順位が高いメッセージがコンシューマに届く場合、すでに届いているメッセージを削除するまで、コンシューマはこのメッセージを受信しません。
コンシューマが、メッセージに対してより効率的にキューのナビゲーションを制御できるように、Oracle Database Advanced QueuingにはJMS拡張機能として複数のナビゲーション・モードが用意されています。これらのモードは、TopicSubscriber
、QueueReceiver
またはTopicReceiver
で設定できます。
グループ化されていないメッセージには、次の2つのモードを使用できます。
-
FIRST_MESSAGE
このモードでは、位置がキューの先頭にリセットされます。コンシューマがキューの最上位にあるメッセージを削除できるため、優先順位に基づくキューで役立ちます。
-
NEXT_MESSAGE
このモードは、コンシューマの確立された位置の後のメッセージを取得します。たとえば、4番目のメッセージの位置で適用された
NEXT_MESSAGE
は、そのキューの5番目のメッセージを取得します。これはデフォルト・アクションです。
グループ化メッセージには、次の3つのモードを使用できます。
-
FIRST_MESSAGE
このモードでは、位置がキューの先頭にリセットされます。
-
NEXT_MESSAGE
このモードでは、位置が同一トランザクションの次のメッセージに設定されます。
-
NEXT_TRANSACTION
このモードでは、位置が次のトランザクションの最初のメッセージに設定されます。
注意:
シャード・キューは、前述の3つのモードをサポートしていません。
次の方法でメッセージが受信される場合、グループ化トランザクションのプロパティを無効にできます。
-
セレクタに相関識別子を指定して受信
-
セレクタにメッセージ識別子を指定して受信
-
トランザクション・グループのメッセージがすべて受信される前にコミット
NEXT
_MESSAGE
またはNEXT
_TRANSACTION
オプションの使用中にコンシューマがキューの最後に到達したとします。ブロッキングreceive()
を指定していた場合は、ナビゲート位置は自動的にそのキューの先頭に変更されます。
デフォルトでは、QueueReceiver
、TopicReceiver
またはTopicSubscriber
は、最初のreceiveコールにFIRST_MESSAGE
を、以降のreceive()
コールにNEXT_MESSAGE
を使用します。
メッセージのブラウズ
デキューするクライアントがキューからメッセージを削除できる通常のreceive
の他に、JMSでは、JMSクライアントがキューで自身のメッセージをブラウズできるようにするインタフェースを提供しています。QueueBrowser
は、QueueSession
からcreateBrowser
メソッドを使用して作成できます。
メッセージが参照されると、そのメッセージは引き続き処理できます。メッセージがブラウズされた後は、同時セッションからreceive
コールがそのメッセージを削除する場合があるため、JMSセッションに引き続き使用できるとはかぎりません。
一度参照したメッセージが同時JMSクライアントによって削除されないようにするために、ロック・モードでメッセージを参照できます。そのためには、JMSインタフェースに対するOracle Database Advanced Queuingの拡張機能を使用して、ロック・モードを持つQueueBrowser
を作成する必要があります。メッセージのロックは、セッションがコミットまたはロールバックを実行すると解放されます。
QueueBrowser
によって参照されたメッセージを削除するには、セッションがQueueReceiver
を作成し、JMSmesssageID
をセレクタとして使用する必要があります。
取出しを伴わないメッセージの削除
コンシューマは、receiveNoData
コールを使用してキューまたはトピックからメッセージを取得することなく、メッセージを削除できます。アプリケーションがQueueBrowser
などを使用してメッセージをすでに確認した場合に役立ちます。このモードを使用すると、JMSクライアントがペイロードをデータベースから取得するオーバーヘッドを回避できます(メッセージが大きい場合、オーバーヘッドが顕著である可能性があります)。
遅延間隔をおいた後の再試行
キュー/トピックからメッセージを受信するトランザクションが失敗した場合、そのメッセージを削除する試行に失敗したとみなされます。Oracle Database Advanced Queuingは、メッセージ削除の試行に失敗した回数をメッセージ履歴に記録します。
アプリケーションでは、メッセージに対する再試行の最大回数をキュー/トピック・レベルで指定できます。メッセージ削除がこの数より多く失敗した場合、メッセージは例外キューに移動されます。
Oracle Database Advanced Queuingでは、ユーザーはmax_retries
とともにretry_delay
も指定できます。これは、受信の試行に失敗したメッセージを、retry_delay
間隔後に引き続きキューで参照し、デキューできることを意味します。それまでこのメッセージはWAITING
状態になります。Oracle Database Advanced Queuingのバックグラウンド・プロセスのタイム・マネージャは、再試行遅延プロパティを強制的に適用します。
再試行の最大回数および再試行の遅延は、キュー/トピックのプロパティです。このプロパティは、キュー/トピックの作成時、またはキュー/トピックに対する変更メソッドを使用して設定できます。MAX_RETRIES
のデフォルト値は5
です。
注意:
シャード・キューは、再試行の遅延をサポートしていません。
MessageListenerを使用したメッセージの非同期受信
JMSクライアントは、setMessageListener
メソッドを使用してMessageListener
を設定することによって、メッセージを非同期的に受信できます。
コンシューマにメッセージが届いた場合、メッセージ・リスナーのonMessage
メソッドがそのメッセージで起動されます。メッセージ・リスナーは、メッセージの受信をコミットまたは異常終了できます。メッセージ・リスナーは、JMS Connection
が停止されている場合、メッセージを受信しません。一度メッセージ・リスナーがコンシューマに対して設定されると、メッセージの受信にreceive
コールを使用することはできません。
JMSクライアントは、セッションでMessageListener
を設定することによって、そのセッションのすべてのコンシューマに対してメッセージを非同期的に受信できます。一度メッセージ・リスナーが設定されると、そのセッションでは、その他のメッセージ受信モードを使用できません。
例外キュー
例外キューは、すべての期限切れのメッセージまたは使用できないメッセージが格納されるリポジトリです。アプリケーションがメッセージを例外キューに直接エンキューすることはできません。ただし、期限切れまたは処理できないメッセージを処理するアプリケーションは、例外キューからこれらのメッセージを受信または削除できます。
例外キューからメッセージを取り出すには、JMSクライアントはPoint-to-Pointインタフェースを使用する必要があります。トピック用のメッセージの例外キューは、使用可能な複数のコンシューマでキュー表に作成する必要があります。他のキューと同様に、例外キューもAQOracleQueue
クラスでstart
メソッドを使用して、メッセージを受信できる必要があります。例外キューをエンキュー可能に設定しようとすると、例外が発生します。
シャード・キューは、DBMS_AQADM.CREATE_EXCEPTION_QUEUE
APIを介して例外キューをサポートするようになりました。
PROCEDURE CREATE_EXCEPTION_QUEUE(
sharded_queue_name IN VARCHAR2,
exception_queue_name IN VARCHAR2 DEFAULT NULL,
multiple_consumers IN BOOLEAN DEFAULT FALSE,
storage_clause IN VARCHAR2 DEFAULT NULL,
sort_list IN VARCHAR DEFAULT NULL,
comment IN VARCHAR2 DEFAULT NULL
);
例外キューは、"JMS_OracleExcpQ"
と呼ばれるOracle固有のメッセージ・プロパティで、メッセージの送信/パブリッシュ前に設定できます。例外キューが指定されていないと、デフォルトの例外キューが使用されます。非シャード・キューの場合、デフォルトの例外キューはキュー表の作成時に自動的に作成され、AQ$_
queue_table_name
_E
と命名されます。デフォルトでは、シャード・キューには例外キューは作成されません。
メッセージは、次の条件が成立するときに例外キューに移されます。
-
そのメッセージが、指定された
timeToLive
内にデキューされなかった場合。複数のサブスクライバを指定したメッセージの場合、指定された
timeToLive
内にそのメッセージをデキューできない受信者が1つ以上あると、メッセージは例外キューに移されます。 -
メッセージが正常に受信されたが、メッセージ処理中のエラーのためアプリケーションが
receive
を実行したトランザクションを異常終了した場合。そのメッセージはキュー/トピックに戻され、メッセージ受信のために待機中のどのアプリケーションでも使用可能になります。アプリケーションがトランザクション全体を異常終了するか、
receive
前のセーブポイントまでロールバックしたときは、receive
がロールバックまたはUNDOされたとみなされます。これは失敗したメッセージ受信の試行であるため、その再試行回数は更新されます。メッセージの再試行回数が、メッセージが常駐するキュー/トピックに指定された最大値を超える場合、そのメッセージは例外キューに移されます。
メッセージが複数のサブスクライバを持つ場合、そのメッセージは、すべての受信者が再試行制限を超えたときにのみ、例外キューに移されます。
注意:
サーバー・プロセスがインスタンスで停止した(ALTER
SYSTEM
KILL
SESSION
またはSHUTDOWN
ABORT
など)ためにデキュー・トランザクションが失敗した場合、RETRY_COUNT
は増分されません。
JMS伝播
この項の内容は次のとおりです。
注意:
シャード・キューは、RemoteSubscriber、伝播のスケジューリング、拡張伝播スケジュール機能および伝播中の例外処理をサポートしていません。
RemoteSubscriber
Oracle Database Advanced Queuingによって、他のデータベースにあるサブスクライバをトピックにサブスクライブできます。トピックに対してパブリッシュされたメッセージがリモート・サブスクライバの基準を満たしている場合は、リモート・サブスクライバに指定されているリモート・データベースにあるキュー/トピックに自動的に伝播します。伝播は、データベース・リンクおよびOracle Net Servicesを使用して実行されます。これによって、同じデータベースに接続しなくても、アプリケーション同士が互いに通信できます。
リモート・サブスクライバを実装するには、次の2つの方法があります。
-
createRemoteSubscriber
メソッドは、トピック上またはトピックに対してリモート・サブスクライバを作成するために使用します。このリモート・サブスクライバは、クラスAQjmsAgent
のインスタンスとして指定されます。 -
AQjmsAgent
には、名前およびアドレスがあります。アドレスは、キュー/トピックおよびサブスクライバのデータベースへのデータベース・リンクで構成されています。
リモート・サブスクライバには、次の2種類があります。
-
リモート・サブスクライバがトピックである場合。
これは、
AQjmsAgent
オブジェクトのリモート・サブスクライバに名前が指定されず、アドレスがトピックである場合に発生します。サブスクライバのサブスクリプションを満たすメッセージが、リモート・トピックに伝播されます。伝播されたメッセージは、それが満たすリモート・トピックのすべてのサブスクリプションに対して使用可能になります。 -
メッセージに対して特定のリモート受信者を指定する場合。
リモート・サブスクリプションは、リモート・データベースにある特定のコンシューマに対して指定できます。リモート受信者の名前が(
AQjmsAgent
オブジェクトに)指定される場合、サブスクリプションを満たすメッセージが、その受信者専用のリモート・データベースに伝播されます。リモート・データベースにある受信者は、TopicReceiver
インタフェースを使用してメッセージを取り出します。リモート・サブスクリプションは、Point-to-Pointキューに対して指定することもできます。
伝播スケジュール
伝播は、メッセージがターゲットの接続先データベースに伝播されるすべてのトピックについて、schedule_propagation
メソッドを使用してスケジューリングされる必要があります。
スケジュールは時間の枠を示し、メッセージはその枠内でソース・トピックから伝播されます。この時間枠は、ネットワーク通信量、ソース・データベースの負荷、接続先データベースの負荷などの複数の要因に左右されます。したがって、スケジュールは特定のソースおよび宛先にあわせて調整する必要があります。スケジュールが作成されると、ジョブは自動的にjob_queue
機能に発行され、伝播が処理されます。
伝播スケジュールのための運用管理コールによって、スケジュール管理を柔軟に行うことができます。あるスケジュールの存続時間または伝播枠パラメータによって、伝播が開始される時間枠が指定されます。存続時間が指定されない場合、時間枠は無制限の単一枠になります。枠を定期的に繰り返す必要がある場合、連続する枠の間の周期的間隔を定義するnext_time
機能を使用して有限の存続時間を指定します。
あるキューに定義された伝播スケジュールは、そのキューの有効期間中いつでも変更または削除できます。さらに、(スケジュールを削除するかわりに)一時的に使用不可にするコール、および使用不可のスケジュールを使用可能にするコールがあります。メッセージがスケジュール内で伝播されているとき、そのスケジュールはアクティブです。すべての管理コールは、スケジュールがアクティブかどうかに関係なく実行されます。スケジュールがアクティブの場合、コールが実行されるまでに数秒かかります。
伝播が開始されるには、ジョブ・キュー・プロセスを起動する必要があります。少なくとも2つのジョブ・キュー・プロセスを起動する必要があります。接続先データベースへのデータベース・リンクも有効にする必要があります。伝播のソースおよび宛先トピックは、同じメッセージ型である必要があります。リモート・トピックは、エンキューできる必要があります。データベース・リンクのユーザーもリモート・トピックに対するエンキュー権限を持つ必要があります。
関連項目:
拡張伝播スケジュール機能
伝播のために定義されたカタログ・ビューは、アクティブ・スケジュールに関する次の情報を提供します。
-
そのスケジュールを処理しているバックグラウンド・プロセスの名前
-
伝播を処理しているセッションのSID(セッションおよびシリアル番号)
-
スケジュールを処理しているインスタンス(Oracle RACを使用している場合)
-
先行して正常に実行されたスケジュール
-
次に実行予定のスケジュール
スケジュールごとに次の伝播統計が保持され、キュー管理者がスケジュール調整に役立てることができます。
-
スケジュールの中で伝播されたメッセージ合計数
-
スケジュールの中で伝播されたバイト合計数
-
伝播枠の中で伝播されたメッセージの最大数
-
伝播枠の中で伝播されたバイトの最大値
-
伝播枠の中で伝播されたメッセージの平均数
-
伝播済メッセージの平均サイズ
-
伝播済メッセージの平均時間
伝播機能には、障害対処およびエラー・レポートが組み込まれています。たとえば、指定されたデータベース・リンクが無効な場合、リモート・データベースが使用できない場合、またはリモート・トピック/キューにエンキューできない場合、適切なエラー・メッセージがレポートされます。伝播は指数バックオフ・スキームを使用して、障害が発生したスケジュールからの伝播を再試行します。あるスケジュールで続けて障害が発生したときは、最初の再試行は30秒後、次の再試行は60秒後、3回目の再試行は120秒後、というように続きます。再試行時間が現行の伝播枠の期限切れ時刻を超える場合は、次の再試行は、次の伝播枠の開始時刻に行われます。最大16回の再試行が行われた後、そのスケジュールは自動的に使用不可能になります。
注意:
再試行が次の伝播ウィンドウに移動されると、常に移動されるようになり、指数バックオフ・スキームは再試行のスケジュールを管理しません。DBMS_AQADM.SCHEDULE_PROPAGATION()
のnext_time
パラメータで指定された日付関数の結果、ウィンドウ間の間隔が短くなると、再試行の失敗数はすぐに16に達し、スケジュールが無効になります。
障害のためにスケジュールが自動的に使用不可になると、関連情報がアラート・ログに書き込まれます。スケジュールで失敗が発生したか、その場合は何回連続して失敗が発生したか、失敗の原因を示すエラー・メッセージ、および最後の失敗が発生した時刻を、いつでも確認できます。この情報を調べることで、管理者は障害を回復し、スケジュールを使用可能にできます。
再試行の間に伝播が成功したときは、障害の数は0(ゼロ)にリセットされます。
伝播機能にはOracle Real Application Clustersサポートが組み込まれていますが、ユーザーおよび管理者には透過的です。伝播を処理するジョブは、ソース・トピックが常駐しているキュー表の所有者と同じインスタンスに送られます。あるインスタンスに障害が発生してトピックを保存しているキュー表が他のインスタンスに移される場合は、伝播ジョブも必ず自動的に新しいインスタンスに移行されます。これによって、インスタンス間のping操作は最小限に抑えられ、パフォーマンスが向上します。伝播は、同時スケジュールをいくつでも処理できるように設計されています。
job_queue_processes
の最大数は1000で、その一部は伝播に関連しないジョブの処理に使用できます。このために、伝播にはマルチタスキングおよびロード・バランシングのサポートが組み込まれています。伝播アルゴリズムは、複数スケジュールが単一スナップショット(job_queue
)のプロセスによって処理できるように設計されています。job_queue
プロセスに対する伝播の負荷は、異なるソース・トピックからのメッセージ到着の割合に基づいて偏りが発生する場合があります。あるプロセスが数個のアクティブ・スケジュールによって過負荷になっている一方で、別のプロセスは受動的なスケジュールが多いために余力があるというとき、伝播はプロセス間で負荷が均等になるようにスケジュールを自動的に再分配します。
伝播中の例外処理
ネットワーク障害のようなシステム・エラーが発生した場合、Oracle Database Advanced Queuingは指数バックオフ・アルゴリズムを使用してメッセージを伝播する試みを継続します。キューからデータベース・リンクへの伝播中のアプリケーション・エラーを示している状況では、Oracle Database Advanced QueuingはそのメッセージにUNDELIVERABLE
というマークを付けてalert.log
に記録します。このようなエラーは、リモート・キューが存在しない場合、またはソース・キューおよびリモート・キューの型が一致しない場合に発生します。background_dump_dest
ディレクトリのトレース・ファイルには、そのエラーに関する追加情報があります。
新規のジョブ・キュー・プロセスが開始すると、型を再検証できるように型の不一致エラーを消去します。ジョブ・キュー・プロセス数に上限を設定して、伝播のビジー状態が続く場合、ジョブ・キュー・プロセスが終了して再開するまで待つ必要はありません。キューの型は、必要に応じてDBMS_AQADM.VERIFY_QUEUE_TYPES
を使用して再検証できます。
注意:
キューからキューへの伝播中に型の不一致が検出されると、伝播は停止してエラーが発生します。このような場合は、DBA_SCHEDULES
ビューを問い合せて、特定の宛先への伝播中に発生した最後のエラーを判断する必要があります。このメッセージには、UNDELIVERABLE
マークは付いていません。
JMS AQのメッセージ変換
あるフォーマットのメッセージを別のフォーマットのメッセージにマップするために変換を定義できます。変換は、同一の情報を異なるフォーマットで表現するアプリケーションを統合する必要がある場合に有効です。変換はSQL式およびPL/SQLファンクションです。メッセージ変換は、標準JMSインタフェースに対するOracle Database Advanced Queuingの拡張機能です。
変換は、DBMS_TRANSFORM.create_transformation
プロシージャを使用して作成できます。変換は、次の操作を行う場合に指定できます。
-
キューまたはトピックへのメッセージの送信
-
キューまたはトピックからのメッセージの受信。
-
TopicSubscriber
の作成 -
RemoteSubscriber
の作成。これによって、異なるフォーマットのトピック間でメッセージを伝播できます。
注意:
JMSシャード・キューは、メッセージ変換をサポートしていません。
JMSストリーミング
AQ JMSは、大量のメッセージ・データまたはペイロードを送受信するアプリケーション用に、AQjmsBytesMessage
およびAQjmsStreamMessage
を介した共有キューのエンキューおよびデキューでのストリーミングをサポートします。
JMSストリーミングは、大きい連続したバイトの配列を送受信するのではなく、メッセージ・ペイロードを小さいチャンクに分割することにより、大きいメッセージを扱うときのメモリー要件を緩和します。JMS標準にストリーミング・メカニズムは含まれないため、AQ JMSはAQストリーミング・エンキューおよびデキュー機能を示すための固有のインタフェースを提供します。これにより、ユーザーは既存のjava入出力ストリームを使用してメッセージ・データまたはペイロードを簡単に送受信できます。
データベースのRDBMS 12.2へのアップグレード時に既存のアプリケーションが変更なしで動作できるように、デフォルトではストリーミングAPIは無効化されます。
クライアント・アプリケーションはシステム・プロパティoracle.jms.useJmsStreaming
をtrue
に設定して使用することにより、JMSストリーミングを有効化できます。
注意:
JMSストリーミングはThinドライバの場合のみサポートされます。
エンキューでのJMSストリーミング
AQ JMSではAQjmsBytesMessage
およびAQjmsStreamMessage
の新しいAPI setInputStream(java.io.InputStream)
が提供され、メッセージ・データ用の入力ストリームを設定します。
/** * @param inputStream - InputStream to read the message payload * @throws JMSException - if the JMS provided fails to read the payload due to * some internal error */ public void setInputStream(InputStream inputStream) throws JMSException
次のコード・スニペットでは、AQjmsBytesMessage
タイプのメッセージが作成され、メッセージ・データ用のFileInputStream
が設定されます。
Session session = connection.createSession(false, Session.CLIENT_ACKNOWLEDGE); Destination destination = session.createQueue("queueName"); MessageProducer producer = session.createProducer(destination); AQjmsBytesMessage bytesMessage = (AQjmsBytesMessage)session.createBytesMessage(); InputStream input = new FileInputStream("somefile.data"); bytesMessage.setInputStream(input); producer.send(bytesMessage);
注意:
-
BytesMessage
およびStreamMessage
のメソッドはjava.io.DataInputStream
およびjava.io.DataOutputStream
で検出されるメソッドに基づいているため、様々なread*()
およびwrite*()
メソッドの意味のある変換はストリームでは不可能です。次の使用例では例外が発生します。-
bytesMessage.setInputStream(input);
bytesMessage.writeInt(99);
-
bytesMessage.writeInt(99);
bytesMessage.setInputStream(input);
-
-
通常のエンキュー操作と同様に、ストリーミングを使用したエンキューは同期操作となり、エンキューが完了した後でのみ、制御がクライアントに戻されます。
-
これらのAPIが明示的にクライアントにより使用される場合にのみ、ストリーミングがエンキューで使用されます。AQ JMSはメッセージ・データのサイズと関係なく、通常のエンキューではストリーミングを使用しません。
デキューでのJMSストリーミング
ストリーミングを使用したデキュー操作は、2つのステップで実行されます。サーバーでは、メッセージ本文のサイズに基づき、メッセージ本文をストリーミングするかどうかが決定されます。デフォルトのしきい値制限は10MBです。そのため、メッセージ本文が10MBよりも大きく、システム・プロパティoracle.jms.useJmsStreamingを使用して、ストリーミングがクライアントで有効な場合、サーバーはデキューでストリーミングを使用します。
-
これはクライアントが
receive()
メソッドを呼び出す場合の通常のデキュー・プロセスです。Destination destination = session.createQueue ("queueName"); AQjmsConsumer consumer = (AQjmsConsumer) session.createConsumer(destination); Message message = consumer.receive(10000);
-
クライアントがペイロードなしのメッセージを受信する場合、クライアントは受信メッセージでの
isLargeBody()
の呼び出しにより、ストリーミングがデキューで使用されるかどうかを特定します。/** * This method can be used by the client applications to check whether the message * contains large messaege body and hence requires streaming with dequeue. * * @return true when the message body is large and server decides to stream * the payload with dequeue */ public boolean isLargeBody()
isLargeBody()
により戻されたtrueの値は、デキューでのストリーミングを示します。デキューでストリーミングを使用する場合、AQ JMSはAQjmsStreamMessage
とAQjmsBytesMessage
に対して正確にメッセージ本文の長さを移入します。そのため、クライアント・アプリケーションはメッセージでgetBodyLength()
を呼び出し、ペイロードのサイズを判断できます。public long getBodyLength()
クライアントがデキューでのストリーミングについて理解したら、受信メッセージで次のAPIのいずれかを使用してメッセージ・データをフェッチできます。
クライアント・アプリケーションは、AQjmsBytesMessage
およびAQjmsStreamMessage
で使用可能な次のAPIを使用して、メッセージ・データを受信できます。
/** * Writes the message body to the OutputStream specified. * * @param outputStream - the OutputStream to which message body can be written * @return the OutputStream containing the message body. * @throws JMSException - if the JMS provided fails to receive the message body * due to some internal error */ public OutputStream getBody(OutputStream outputStream) throws JMSException /** * Writes the message body to the OutputStream specified, with chunkSize bytes * written at a time. * * @param outputStream - the OutputStream to which message body can be written * @param chunkSize - the number of bytes to be written at a time, default value * 8192 (ie. 8KB) * @return the OutputStream containing the message body. * @throws JMSException - if the JMS provided fails to receive the message body * due to some internal error */ public OutputStream getBody(OutputStream outputStream, int chunkSize)throws JMSException /** * Writes the message body to the OutputStream specified. This method waits until * the message body is written completely to the OutputStream or the timeout expires. * * A timeout of zero never expires, and a timeout of negative value is ignored. * * @param outputStream - the OutputStream to which message body can be written * @param timeout - the timeout value (in milliseconds) * @return the OutputStream containing the message body. * @throws JMSException - if the JMS provided fails to receive the message body * due to some internal error */ public OutputStream getBody(OutputStream outputStream, long timeout) throws JMSException /** * Writes the message body to the OutputStream specified, chunkSize bytes at a time. * This method waits until the message body is written completely to the OutputStream * or the timeout expires. * * A timeout of zero never expires, and a timeout of negative value is ignored. * * @param outputStream - the OutputStream to which message body can be written * @param chunkSize - the number of bytes to be written at a time, * default value 8192 (ie. 8KB) * @param timeout - the timeout value (in milliseconds) * @return the OutputStream containing the message body. * @throws JMSException - if the JMS provided fails to receive the message body * due to some internal error */ public OutputStream getBody(OutputStream outputStream, int chunkSize, long timeout) throws JMSException
次のコード・スニペットは、ストリーミングがデキューで使用され、受信したペイロードがFileOutputStream
に書き込まれるかどうかをチェックします。
if (message instanceof BytesMessage && (AQjmsBytesMessage)message.isLargeBody()){ // optional : check the size of the payload and take appropriate action before // receiving the payload. (AQjmsBytesMessage) message.getBody(new FileOutputStream(new File("…"))); } else { // normal dequeue }
通常、両方のステップが完了すると、メッセージは完全に消費されたとみなされます。AQサーバーにより、ステップ1の後でメッセージでのロックは保持され、ステップ2の後でのみ解除されます。
メッセージ・コンシューマによりメッセージが部分的に消費されることにより発生する可能性のある問題を考慮して、確認モードCLIENT_ACKNOWLEDGE
およびSESSION_TRANSACTED
でのセッション用のストリーミングAPIは制限されました。
そのため、部分的に消費されたメッセージを含む、すべてのメッセージは、次の時点で完全に消費されたとみなされます。
-
message.acknowledge()
はCLIENT_ACKNOWLEDGE
セッションで呼び出されます。 -
セッションの
commit()
はトランザクション・セッションで呼び出されます。
通常の場合、セッションrollback()
は、そのセッションで受信したメッセージをロールバックします。
JMSストリーミングは使用可能ですが、次の制限があります。
-
ストリーミングはデフォルトで無効化されており、システム・プロパティ
oracle.jms.useJmsStreaming
を使用してクライアント・アプリケーションにより有効化できる -
メッセージ・データのサイズがしきい値よりも大きい場合に、デキューでストリーミングが使用されます。デフォルトのしきい値は10MBです。
-
ストリーミング・サポートは
AQjmsBytesMessage
およびAQjmsStreamMessage
で使用可能 -
ストリーミング・サポートは共有キューでのみ使用可能
-
ストリーミング・サポートはThinドライバでのみ使用可能
-
ストリーミング・サポートは、メッセージ・プロデューサがメッセージ配信モードに
NON_PERSISTENT
を使用しているときは使用できない -
ストリーミングはメッセージ・リスナーではサポートされません。そのため、MessageConsumerにメッセージ・リスナー・セットがある場合、およびメッセージ・データがしきい値制限を超えている場合は、内部的に通常のデキューが使用されます。
-
ストリーミング・サポートは、確認モード
CLIENT_ACKNOWLEDGE
およびSESSION_TRANSACTED
を使用してセッションで使用可能です。
Java EEの準拠
Oracle JMSは、Oracle Sun Microsystems JMS 1.1標準に準拠しています。実行時に、Oracle Java Message Service (Oracle JMS)クライアントに対してJava EE準拠モードを定義できます。準拠モードにするには、コマンドライン・オプションとしてJavaプロパティ oracle.jms.j2eeCompliant
をTRUE
に設定します。非準拠モードにする場合は何もしません。FALSE
がデフォルト値です。
Java EE準拠をサポートし、非準拠モードでも使用できるOracle Database Advanced Queuingの機能は次のとおりです。
-
非トランザクション・セッション
-
永続サブスクライバ
-
一時キューおよびトピック
-
非永続配信モード
-
AQ$_JMS_MESSAGE
型のOracle Database Advanced Queuingキューを使用した単一のJMSキューまたはトピックに対する複数のJMSメッセージ・タイプ -
永続サブスクライバに対する
noLocal
オプション -
JMSシャード・キューはJMSでネイティブにサポートされており、Java EEコンプライアンスに準拠しています
関連項目:
-
『Java Message Service Specification』、バージョン1.1、2002年3月18日、Sun Microsystems, Inc.
-
JMSPriorityおよびJMSExpirationに対するJavaプロパティ
oracle.jms.j2eeCompliant
の影響の詳細は、「JMSメッセージ・ヘッダー」を参照してください。 -
永続サブスクライバに対するJavaプロパティ
oracle.jms.j2eeCompliant
の影響の詳細は、「DurableSubscriber」を参照してください。