Oracle® TimesTen In-Memory Database

Java開発者ガイド

11gリリース2(11.2.2)

B66445-06(原本部品番号:E21638-10)

2015年3月

Oracle TimesTen In-Memory Database Java開発者ガイド, 11gリリース2(11.2.2)

B66445-06

Copyright © 1996, 2015, Oracle and/or its affiliates.All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社との間で該当する取決めにて別途規定しないかぎり、オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社との間で該当する取決めにて別途規定する場合を除き、オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

目次

タイトルおよび著作権情報

はじめに

- 対象読者

- 関連ドキュメント

- 表記規則

- ドキュメントのアクセシビリティについて

新機能

- リリース11.2.2.0.0の新機能

1 Java開発環境

- TimesTenおよびJDKのインストール

- Java開発環境の構成

- Javaアプリケーションのコンパイル

- TimesTen Javaのデモ

2 JDBCでのTimesTenデータベースの使用

- 重要なJDBCクラスおよびインタフェース

- パッケージのインポート

- java.sqlパッケージのインタフェースのサポート

- java.sqlパッケージのクラスのサポート

- javax.sqlパッケージのインタフェースとクラスのサポート

- TimesTen JDBC拡張

- その他のTimesTenクラスおよびインタフェース

- TimesTenデータベース接続の管理

- データベースの接続URLの作成および接続属性の指定

- データベースへの接続

- データベースからの切断

- 直接接続のオープンおよびクローズ

- データベースの妥当性の確認

- 接続のアクセス制御

- TimesTenデータの管理

- 単純なSQL文の実行

- TimesTen結果セットの使用: ヒントおよび制限

- 複数のデータ行のフェッチ

- パラメータのバインドと文の実行

- SQL文の準備および入力パラメータの設定

- 出力および入力/出力パラメータの使用

- SQL文での重複したパラメータのバインド

- PL/SQLでの重複したパラメータのバインド

- 連想配列のバインド

- REF CURSORの使用

- DML RETURNING(RETURNING INTO句)の使用

- ROWIDの使用

- LOBの作業

- LOBの概要

- JDBCでのLOB

- TimesTenのLOBとOracle DatabaseのLOBの違い

- LOBファクトリ・メソッド

- LOBのgetterメソッドとsetterメソッド

- TimesTenのLOBインタフェース・メソッド

- LOBのプリフェッチ

- パススルーLOB

- データベースに対する変更のコミットまたはロールバック

- 自動コミットの設定

- 手動コミットまたは変更のロールバック

- COMMIT文およびROLLBACK SQL文の使用

- 複数スレッドの管理

- Javaのエスケープ構文およびSQLファンクション

- その他のTimesTenデータ管理機能の使用

- プロシージャおよびファンクションを実行するためのCALLの使用

- SQL文の実行に対するタイムアウトまたはしきい値の設定

- SQL文のタイムアウト期間の設定

- SQL文のしきい値期間の設定

- TimesTen Cacheで使用する機能

- ttOptSetFlag組込みプロシージャでの一時パススルー・レベルの設定

- キャッシュ・グループの管理

- レプリケーションで使用する機能

- アクセス制御のためのTimesTen機能の検討

- エラー処理

- 致命的エラー、致命的でないエラーおよび警告

- 致命的エラーの処理

- 致命的ではないエラーの処理

- 警告について

- 異常終了

- エラーおよび警告のレポート

- 特定のエラーの検出および対応

- 失敗したトランザクションのロールバック

- 自動クライアント・フェイルオーバーのJDBCサポート

- 自動クライアント・フェイルオーバーのJDBCサポートの特徴および機能

- 一般的なクライアント・フェイルオーバー機能

- プールされた接続のクライアント・フェイルオーバー機能

- 自動クライアント・フェイルオーバーの構成

- 自動クライアント・フェイルオーバーの同期検出

- 自動クライアント・フェイルオーバーの非同期検出

- クライアント・フェイルオーバー・イベント・リスナーの実装

- クライアント・フェイルオーバー・リスナー・インスタンスの登録

- クライアント・フェイルオーバー・リスナー・インスタンスの削除

3 イベント管理のためのJMS/XLAの使用

- JMS/XLAの概念

- XLAでレコードをトランザクション・ログから読み取る方法

- XLAおよびマテリアライズド・ビュー

- XLAブックマーク

- ブックマークの使用方法

- レプリケート済ブックマーク

- XLAブックマークおよびトランザクション・ログの保持

- JMS/XLA構成ファイルおよびXLAトピック

- XLA更新

- XLA応答モード

- 更新のプリフェッチ

- 更新の確認

- アクセス制御がXLAに与える影響

- XLAの制限事項

- JMS/XLAとOracle GDKの依存性

- XLAへの接続

- 表への更新の監視

- 更新の受信および処理

- JMS/XLAアプリケーションの終了

- 接続のクローズ

- ブックマークの削除

- 表からのサブスクライブ解除

- レプリケーション・メカニズムとしてのJMS/XLAの使用

- ターゲット・データベースへのJMS/XLAメッセージの適用

- TargetDataStoreのエラー・リカバリ

4 分散トランザクション処理: JTA

- JTAの概要

- X/Open DTPモデル

- 2フェーズ・コミット

- TimesTenでのJTAの使用

- XAに対するTimesTenデータベースの要件

- TimesTenでのグローバル・トランザクションのリカバリ

- TimesTenでのXAエラーの処理

- JTA APIの使用

- 必要なパッケージ

- TimesTen XAConnectionオブジェクトの作成

- XAResourceおよびConnectionオブジェクトの作成

5 Javaアプリケーションのチューニング

- JDBCアプリケーションのチューニング

- 準備された文のプールの使用

- バッチ実行にパラメータの配列を使用

- TimesTenデータ行のバルク・フェッチ

- ResultSetメソッドgetString()の限定的使用

- データ型の変換の回避

- 接続、文、結果セットのクローズ

- JMS/XLAアプリケーションのチューニング

- xlaPrefetchパラメータの設定

- 更新確認の頻度の減少

- 高いイベント率の処理

6 JMS/XLAリファレンス

- JMS/XLA MapMessageの内容

- XLA更新タイプ

- XLAフラグ

- DMLイベント・データの書式

- 表データ

- 行データ

- コンテキスト情報

- DDLイベント・データの書式

- CREATE_TABLE

- DROP_TABLE

- CREATE_INDEX

- DROP_INDEX

- ADD_COLUMNS

- DROP_COLUMNS

- CREATE_VIEW

- DROP_VIEW

- CREATE_SEQ

- DROP_SEQ

- CREATE_SYNONYM

- DROP_SYNONYM

- TRUNCATE

- データ型のサポート

- データ型のマッピング

- データ型キャラクタ・セット

- イベント処理用のJMSクラス

- JMS/XLAレプリケーションAPI

- TargetDataStoreインタフェース

- TargetDataStoreImplクラス

- JMSのメッセージ・ヘッダー・フィールド

索引

はじめに

Oracle TimesTen In-Memory Database (TimesTen)は、迅速な応答およびスループット用にメモリーが最適化されたリレーショナル・データベースです。実行時にはデータベース全体がメモリーに常駐し、リカバリおよび再起動できるようにディスク記憶域に保存されます。レプリケーション機能によって、高可用性が実現します。TimesTenでは、OracleインタフェースであるPL/SQL、OCIおよびPro*C/C++に加えて、標準的なアプリケーション・インタフェースであるJDBC、ODBCおよびODP.NETがサポートされます。TimesTenは、単独で使用することもOracle Databaseのキャッシュとして使用することもできます。

このドキュメントでは、JDBC用のTimesTenのサポートについて説明しています。

内容は次のとおりです。

- 対象読者

- 関連ドキュメント

- 表記規則

- ドキュメントのアクセシビリティについて

対象読者

このマニュアルは、JDBCを介してTimesTenを使用するアプリケーションの開発者またはサポート担当者を対象としています。

JDBCの理解に加えて、TimesTen、SQL(Structured Query Language)およびデータベース処理に関する理解も必要です。

関連ドキュメント

TimesTenのドキュメントは、次の場所のOracle Technology Networkで入手できます。

http://www.oracle.com/technetwork/database/database-technologies/timesten/documentation/index.html

java.sqlパッケージ内の標準JDBC (Java SE)クラスおよびインタフェースに関するJavadocは、次の場所で入手できます(1つ目はJava 6用、2つ目はJava 5.0用)。

http://docs.oracle.com/javase/6/docs/api/java/sql/package-summary.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/package-summary.html

標準Java EEクラスおよびインタフェースに関するJavadocは、次の場所で入手できます(1つ目はJava 6用、2つ目はJava 5.0用)。

http://docs.oracle.com/javaee/6/api/
http://docs.oracle.com/javaee/5/api/

Oracle Databaseのドキュメントは、Oracle Technology Networkでも入手できます。これは、TimesTenでサポートされているが、詳しく説明されていないOracle Databaseの機能の場合に役立ちます。

http://www.oracle.com/pls/db112/homepage

特に、次のOracle Databaseドキュメントが役立ちます。

- 『Oracle Database SQL言語リファレンス』

- 『Oracle Database JDBC開発者ガイド』

表記規則

TimesTenは複数のプラットフォームをサポートしています。このマニュアルに記述されている内容は、特に表記しないかぎり、サポートされるすべてのプラットフォームに適用されます。Windowsという場合、サポートされるすべてのWindowsプラットフォームを指します。UNIXという用語は、サポートされるすべてのUNIXおよびLinuxプラットフォームを表します。TimesTenでサポートされる具体的なプラットフォームのバージョンについては、『Oracle TimesTen In-Memory Databaseリリース・ノート』のプラットフォームに関する項を参照してください。

注意:
TimesTenドキュメントでは、用語としての「データ・ストア」と「データベース」は同じです。両方の用語は、TimesTenデータベースを指します。

このマニュアルでは次の表記規則を使用します。

規則

意味

イタリック体

イタリックは、テキストで定義される用語、ドキュメントのタイトルまたは強調を示します。

固定幅フォント

固定幅フォントは、コード、コマンド、URL、クラス名、インタフェース名、メソッド名、ファンクション名、属性名、ディレクトリ名、ファイル名、画面に表示されるテキスト、または入力するテキストを示します。

固定幅フォントのイタリック

固定幅フォントのイタリックは、コード例で特定の値を指定または使用するプレースホルダまたは変数を示します。次に例を示します。
Driver=install_dir/lib/libtten.sl

install_dirをご使用のTimesTenインストール・ディレクトリに置き換えます。

[ ]

大カッコは、カッコ内の項目を任意に選択することを表します。大カッコは、入力しないでください。

{ }

中カッコは、カッコ内の項目のうち、1つが必須であることを表します。中カッコは、入力しないでください。

|

選択項目の引数を区切る縦線(パイプ)。

. . .

引数の後の水平の省略記号は、1行のコマンドラインで複数の引数を使用できることを表します。コード例の中の水平の省略記号は、例の一部だけが表示されていることを示します。

%

%は、UNIXのシェル・プロンプトを表します。

TimesTenのマニュアルでは、次の変数を使用して、パス、ファイルおよびユーザー名を表します。

規則

意味

install_dir

TimesTenがインストールされているディレクトリのパスです。

TTinstance

TimesTenのインストールで指定するインスタンス名です。インストール時に、一意のインスタンス名でTimesTenの各インストールを識別する必要があります。この名前はインストール・パスに表示されます。

bitsまたはbb

32または64の2桁の数字は、32-bitまたは64-bitのオペレーティング・システムを表します。

releaseまたはrr

リリース番号の最初の3つの部分(ドットが付く場合と付かない場合があります)。リリース番号の最初の3つの部分は、TimesTenのメジャー・リリースを表します。たとえば、1122または11.2.2は、TimesTen 11gリリース2(11.2.2)を表します。

jdk_ver

JDKのメジャー・リリースを表す1または2桁のバージョン番号です。たとえばJDK 1.4の場合は14で、JDK 5.0の場合は5です。

DSN

TimesTenデータソースの名前(TimesTenデータベース用)です。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

サポートをご契約のお客様には、My Oracle Supportを通して電子支援サービスを提供しています。詳細情報は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info)か、聴覚に障害のあるお客様は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs)を参照してください。

新機能

この項では、このマニュアルで説明するOracle TimesTen In-Memory Database 11gリリース2(11.2.2)の新機能の概要、および各機能の詳細への参照先を示します。

リリース11.2.2.0.0の新機能

- LOBサポート
TimesTenでは、LOB(ラージ・オブジェクト)をサポートしています。これには、CLOB(Character LOB)、NCLOB(National Character LOB)およびBLOB(Binary LOB)が含まれます。

JDBCでのサポートの詳細は、「LOBの作業」を参照してください。

- 連想配列バインド
TimesTen JDBCでは、TimesTen PL/SQLへのIN、OUTまたはIN OUTバインド・パラメータである、以前の索引付き表またはPL/SQL表と呼ばれていた連想配列バインドをサポートしています。連想配列では、アプリケーションとデータベース間で効率的にデータの配列を渡すことを可能にします。

「連想配列のバインド」を参照してください。

1 Java開発環境

この章では、Java開発環境およびこれに関連する検討事項について説明します。内容は次のとおりです。

- TimesTenおよびJDKのインストール

- Java開発環境の構成

- Javaアプリケーションのコンパイル

- TimesTen Javaのデモ

TimesTenおよびJDKのインストール

TimesTenは『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』の説明に従い、Java JDKはJavaのインストール・マニュアルの説明に従い、インストールおよび構成します。Java開発環境を構成する際、『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』では、特に次のトピックへの関心が高いことでしょう。

- 「Java環境変数」

- 「環境変数」

TimesTenをインストールおよび構成したら、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータベースの管理に関する説明に従って、データベースDSNを作成します。特に、次の項を参照してください。

- 「TimesTen JDBCドライバおよびドライバ・マネージャを使用した接続」

- 「ユーザーDSNおよびシステムDSNの概要」

- 「直接接続またはクライアント/サーバー接続用のDSNの定義」

- 「TimesTenを使用したスレッド・プログラミング」

- 「UNIXでのData Manager DSNの作成」または「WindowsでのData Manager DSNの作成」

Java開発環境の構成

TimesTen用のJavaアプリケーションの開発を始める前に、環境を適切に構成する必要があります。これには、環境変数を適切に設定することが含まれます。PATH、CLASSPATH、THREAD_FLAGSおよび共有ライブラリ・パス環境変数を含むJavaの環境変数の詳細は、『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』のJava環境変数に関する項を参照してください。

環境変数およびInstant Clientへのランタイム・アクセスは、適切なttenvスクリプト(UNIXプラットフォームの場合install_dir/binディレクトリ: ttenv.shおよびttenv.csh(シェルに応じていずれかを使用)およびWindowsプラットフォームの場合ttenv.bat)により構成されます。詳細は、『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』の環境変数に関する項を参照してください。

注意:
TimesTenには、JDBCの特定の機能および処理で必要なOracle Instant Clientが含まれています。

Javaアプリケーションのコンパイル

『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』のJava環境変数に関する説明では、TimesTenでJavaアプリケーションをコンパイルする際のCLASSPATHの設定について説明しています。

すべてのJavaアプリケーションのコンパイルでは、ご使用のJDK用のJARファイルがクラスパスに存在する必要があります。TimesTenでは、JDK 5.0およびJDK 6用にそれぞれ次のとおりになります。

install_dir/lib/ttjdbc5.jar
install_dir/lib/ttjdbc6.jar

また、すべてのJMS/XLAアプリケーションのコンパイルには、次がクラスパスに存在する必要があります。

install_dir/lib/timestenjmsxla.jar
install_dir/3rdparty/jms1.1/lib/jms.jar
install_dir/lib/orai18n.jar

TimesTen Javaのデモ

Java環境を構成した後、TimesTenクイック・スタート・デモ・アプリケーションをコンパイルして実行することで、すべてが正しく設定されていることを確認できます。クイック・スタートのようこそページ(install_dir/quickstart.html)のサンプル・プログラムの下にあるリンクで、次の事項の説明を参照してください。

- デモ・スキーマおよび設定: build_sampledbスクリプト(Windowsでは.bat、UNIXでは.sh)で、サンプル・データベースおよびデモ・スキーマを作成します。デモの使用を開始する前に、これを使用する必要があります。

- デモ環境および設定: ttquickstartenvスクリプト(通常、TimesTenの設定に使用するttenvスクリプトのスーパーセット)(UNIXでは.shまたは.csh、Windowsでは.bat)によって、デモ環境を設定します。いずれかのデモをコンパイルまたは実行するセッションに入るたびに、これを使用する必要があります。

- デモおよび設定: quickstart/sample_codeディレクトリの下に、JDBCおよびJMS/XLA用のデモがあります。デモのコンパイルおよび実行方法については、サブディレクトリにあるREADMEファイルを参照してください。

- デモの概要: それぞれのデモの概要は、「SAMPLE PROGRAMS」の下で「JDBC (Java)」をクリックして確認できます。TimesTenのJavaの基本デモは、level1、level2、level3およびlevel4と名前がつけられています。levelのデモのデータファイルはjdbc/datfilesディレクトリ内にあります。

注意:
すべてのlevelデモでは、データベースに対する直接接続とクライアント/サーバー接続の両方をサポートしています。

2 JDBCでのTimesTenデータベースの使用

この章では、Javaアプリケーションを作成してデータにアクセスする基本的な手順について説明します。TimesTenアプリケーションを作成する前に、前提条件となる次のタスクがすべて完了している必要があります。

前提条件タスク

実行内容

データベースの作成。

『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータベースの管理に関する手順に従います。

Java環境の構成。

「Java開発環境の構成」の手順に従います。

TimesTen Javaのデモのコンパイルおよび実行。

「TimesTen Javaのデモ」の手順に従います。

TimesTen Javaのデモを正しく実行すると、開発環境が適切に設定され、データベースにアクセスするアプリケーションの作成の準備が完了します。

この章には、次の各項目が含まれます。

- 重要なJDBCクラスおよびインタフェース

- TimesTenデータベース接続の管理

- TimesTenデータの管理

- その他のTimesTenデータ管理機能の使用

- アクセス制御のためのTimesTen機能の検討

- エラー処理

- 自動クライアント・フェイルオーバーのJDBCサポート

重要なJDBCクラスおよびインタフェース

この項では、重要な標準とTimesTen固有のJDBCパッケージ、クラスおよびインタフェースについて説明します。次の内容を含みます。

- パッケージのインポート

- java.sqlパッケージのインタフェースのサポート

- java.sqlパッケージのクラスのサポート

- javax.sqlパッケージのインタフェースとクラスのサポート

- TimesTen JDBC拡張

- その他のTimesTenクラスおよびインタフェース

標準JDBCの詳細は、java.sqlパッケージに関する次の情報を参照してください(1つ目はJava 6用、2つ目はJava 5.0用)。

http://docs.oracle.com/javase/6/docs/api/java/sql/package-summary.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/package-summary.html

TimesTen JDBC拡張のリファレンス情報は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

注意:
TimesTenではJava 6を使用することを推奨します。Java 6のAPIは、特にLOBの操作においてより機能があります。

パッケージのインポート

JDBCを使用するJavaプログラムには、標準のJDBCパッケージをインポートする必要があります。

import java.sql.*;

データ・ソースまたはプールされている接続を使用する場合は、標準拡張JDBCパッケージもインポートする必要があります。

import javax.sql.*;

TimesTen JDBCパッケージをインポートする必要があります。

import com.timesten.jdbc.*;

JTAにXAデータ・ソースを使用するには、次のTimesTenパッケージもインポートする必要があります。

import com.timesten.jdbc.xa.*;

java.sqlパッケージのインタフェースのサポート

TimesTenでは、表2-1のとおり、java.sqlインタフェースをサポートしています(ここには、TimesTenでのサポートにおける注意事項も記載しています)。

「TimesTen JDBC拡張」も参照してください。

表2-1 サポートされているjava.sqlインタフェース

java.sqlのインタフェース

TimesTenでのサポートにおける注意事項

Blob

- 指定したバイト・パターンまたはBLOBパターンが開始する位置を戻すposition()メソッドはサポートされていません。

- Java 5.0ではfree()またはgetBinaryStream(pos,length)はサポートされていませんが、TimesTenでは拡張として提供されています。これらはJava 6では標準です。

CallableStatement

- 名前ではなく、位置を使用してパラメータをCallableStatementに渡す必要があります。

- SQLのエスケープ構文は使用できません。

- これらは、Array、StructまたはRefではサポートされていません。

- setDate()、getDate()、setTime()またはgetTime()のCalendarはサポートされていません。

Clob

- 指定した文字パターンまたはCLOBパターンが開始する位置を戻すposition()メソッドはサポートされていません。

- Java 5.0ではfree()またはgetCharacterStream(pos,length)をサポートしていませんが、TimesTenでは拡張として提供されています。これらはJava 6では標準です。

Connection

- セーブポイントはサポートされていません。

DatabaseMetaData

- 制限はありません。

NClob

- NClobは、Java 6のみでサポートされています(ttjdbc6.jar)。

- 指定した文字パターンまたはNCLOBパターンが開始する位置を戻すposition()メソッドはサポートされていません。

ParameterMetaData

- JDBCドライバは、列がNULL値可能かどうかを判別できません。また、isNullable()へのコールからは、常にparameterNullableUnknownを返します。

- getScale()メソッドは、VARCHAR、NVARCHARおよびVARBINARYのデータ型がINLINEの場合、それらに対して1を返します。(スケールは、これらのデータ型では重要ではありません。)

PreparedStatement

- PreparedStatementのgetMetaData()はサポートされていません。

- これらは、Array、StructまたはRefではサポートされていません。

- setDate()、getDate()、setTime()またはgetTime()にCalendar型はサポートされていません。

ResultSet

- ResultSetでは、getMetaData()をサポートしています。

- 1つの文に複数のオープンResultSetオブジェクトを持つことはできません。

- 結果セットの保持可能性は指定できないため、カーソルのコミット後に、そのカーソルをオープンしたままにできません。

- スクロール可能な結果セットおよび更新可能な結果セットはサポートされていません。

- これらは、Array、StructまたはRefではサポートされていません。

- setDate()、getDate()、setTime()またはgetTime()にCalendar型はサポートされていません。

- 「TimesTen結果セットの使用: ヒントおよび制限」を参照してください。

ResultSetMetaData

- getPrecision()メソッドは、精度が未定義の場合に0を返します。

- getScale()メソッドは、スケールが未定義の場合に-127を返します。

RowId

- RowIdは、Java 6のみでサポートされています(ttjdbc6.jar)。

- ROWIDデータ型には、RowIdインタフェースを使用してアクセスできます。

- 出力および入力/出力行IDはTypes.ROWIDとして登録できます。

- メタデータ・メソッドによって、Types.ROWIDとRowIdの適切なものが返されます。

Statement

- 制限はありません。

- TimesTenでは、cancel()メソッドはODBC関数SQLCancelに委譲します。この関数のTimesTen実装の詳細は、『Oracle TimesTen In-Memory Database C開発者ガイド』のサポートされているODBC関数に関する説明を参照してください。

- getUpdateCount()メソッドのキャッシュ・グループでの特別なTimesTen機能は、「キャッシュ・グループの管理」を参照してください。

java.sqlパッケージのクラスのサポート

TimesTenでは、次のjava.sqlクラスをサポートしています。

- DataTruncation

- Date

- DriverManager

- DriverPropertyInfo

- Time

- Timestamp

- Types

- SQLException

- SQLWarning

javax.sqlパッケージのインタフェースとクラスのサポート

TimesTenでは、次のjavax.sqlインタフェースをサポートしています。

- DataSourceはTimesTenDataSourceで実装されています。

- PooledConnectionは、ObservableConnectionで実装されています。

- ConnectionPoolDataSourceはObservableConnectionDSで実装されています。

- XADataSourceはTimesTenXADataSource(com.timesten.jdbc.xaパッケージ内)で実装されています。

重要:
TimesTen JDBCドライバ自身は、データベース接続プールを実装していません。ObservableConnectionおよびObservableConnectionDSクラスは、標準Java EEインタフェースを実装しているだけであり、Java EE標準に基づいたデータベース接続プールの作成および管理を簡単に行えます。
サンプルのTimesTen接続プール・パッケージはクイック・スタート・デモの一部として提供されています。これは、次のディレクトリにあります。

install_dir/quickstart/sample_code/jdbc/connectionpool

TimesTenでは、次のjavax.sqlイベントおよびリスナーをサポートしています。

- PooledConnectionインスタンスの使用時、ConnectionEventListenerインスタンスを登録しConnectionEventの出現をリスニングできます。

注意:
TimesTenではStatementEventListenerインスタンスは登録できますが、StatementEventインスタンスはサポートされていません。

TimesTen JDBC拡張

ほとんどの場合、TimesTenでサポートされている標準JDBC機能を使用することができます。

また、TimesTen固有の機能のためのcom.timesten.jdbcパッケージには、次の拡張機能もあります。

表2-2 TimesTen JDBC拡張

インタフェース

拡張

注意事項

TimesTenBlob

Blob

BlobインスタンスはTimesTenBlobにキャストできます。これには、LOBがOracle DatabaseパススルーLOBであるかを示したり、LOBリソースを解放したり(Java 5.0にはありません)、位置と長さの指定とともにバイナリ・ストリームを取得する(Java 5.0にはないシグネチャ)機能があります。

「LOBの作業」を参照してください。

TimesTenCallableStatement

CallableStatement

PL/SQL REF CURSORのサポート。「REF CURSORの使用」を参照してください。

入力パラメータを設定し出力パラメータを取得および登録するメソッドとともに、連想配列バインドをサポートしています。「連想配列のバインド」を参照してください。

TimesTenClob

Clob

ClobインスタンスはTimesTenClobにキャストできます。これには、LOBがOracle DatabaseパススルーLOBであるかを示したり、LOBリソースを解放したり(Java 5.0にはありません)、位置と長さの指定とともに文字のストリームを取得する(Java 5.0にはないシグネチャ)機能があります。

「LOBの作業」を参照してください。

TimesTenConnection

Connection

これには、パフォーマンスを向上する行のプリフェッチ、自動クライアント・フェイルオーバーのためのイベントのリスニング、レプリケーション・トラックを指定するパラレル・レプリケーション・スキームのためのトラック番号の設定、データベースの妥当性確認の機能を含みます。

詳細は、「複数のデータ行のフェッチ」、「一般的なクライアント・フェイルオーバー機能」、「レプリケーションで使用する機能」、「データベースの妥当性の確認」を参照してください。

Java 5.0用にファクトリ・メソッドcreateBLOB()およびcreateCLOB()を提供します。(LOBファクトリ・メソッドはJava 5.0にはありません。)「LOBの作業」を参照してください。

TimesTenNClob

NClob

NClobインスタンスはTimesTenNClobにキャストできます(Java 6のみ)。これには、LOBがOracle DatabaseパススルーLOBであるかどうかを示す機能を含みます。

「LOBの作業」を参照してください。

TimesTenPreparedStatement

PreparedStatement

DML RETURNINGのサポート。「DML RETURNINGの使用(RETURNING INTO句)」を参照してください。

入力パラメータを設定するメソッドとともに連想配列のバインドをサポートしています。「連想配列のバインド」を参照してください。

TimesTenStatement

Statement

問合せのしきい値を指定する機能を提供します。「SQL文のしきい値期間の設定」を参照してください。

その他のTimesTenクラスおよびインタフェース

前述の実装に加えて、com.timesten.jdbcパッケージには、次のクラスおよびインタフェースがあります。これらのクラスおよびインタフェースでサポートされた機能は、この章の後半で説明します。

その他のTimesTenインタフェース

- REF CURSORのためのTimesTen型の拡張に、TimesTenTypesを使用します。

- 自動クライアント・フェイルオーバー機能に、ClientFailoverEventListener(および次に説明するClientFailoverEventクラス)を使用します。「自動クライアント・フェイルオーバーのJDBCサポート」を参照してください。

- SQL例外に使用されるベンダー・コードに、TimesTenVendorCodeを使用します。

その他のTimesTenクラス

- 自動クライアント・フェイルオーバー機能に、ClientFailoverEvent(および前述のClientFailoverEventListenerインタフェース)を使用します。

TimesTenデータベース接続の管理

作成するDSNのタイプは、アプリケーションがデータベースに直接接続するか、クライアント接続するかによって異なります。データベースに直接接続する場合は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のUNIXでのData Manager DSNの作成に関する説明またはWindowsでのData Manager DSNの作成に関する説明に従ってDSNを作成してください。データベースへのクライアント接続を作成する場合は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のWindowsでのクライアントDSNの作成および構成に関する説明またはUNIXでのクライアントDSNの作成および構成に関する説明に従ってDSNを作成してください。

DSNを作成すると、アプリケーションはデータベースに接続できます。この項では、JDBC直接ドライバまたはJDBCクライアント・ドライバを使用して、データベースへのJDBC接続を作成する方法について説明します。

この項で説明する操作は、level1デモに基づいています。「TimesTen Javaのデモ」を参照してください。

ここでは次の内容について説明します。

- データベースの接続URLの作成および接続属性の指定

- データベースへの接続

- データベースからの切断

- 直接接続のオープンおよびクローズ

- 接続のアクセス制御

注意:
TimesTenドライバのロード(Java 5.0):
TimesTenではJava 6を使用することを推奨します。ただし、Java 5.0を使用する場合は、データベース接続の作成に利用できるようTimesTenドライバを明示的にロードする必要があります(しない場合、アプリケーションが接続を試行する際、TimesTenによってエラーが返されます)。この手順は、Java 6では不要です。

次に、(直接接続用とクライアント/サーバー接続用の)TimesTen JDBCドライバを示します。

com.timesten.jdbc.TimesTenDriver
com.timesten.jdbc.TimesTenClientDriver

Java 5.0でTimesTenへの接続にDriverManagerインタフェースを使用する場合、Class.forName()メソッドをコールして、TimesTen JDBCドライバをロードします。このメソッドによって、TimesTenドライバのインスタンスが作成され、ドライバ・マネージャに登録されます。TimesTenDataSourceインタフェースを使用している場合、Class.forName()をコールする必要はありません。

TimesTen直接ドライバを特定およびロードする例を次に示します。

Class.forName("com.timesten.jdbc.TimesTenDriver");

データベースの接続URLの作成および接続属性の指定

JDBC接続を作成するには、データベースのTimesTen接続URLを指定する必要があります。TimesTen接続URLの形式は、次のとおりです。

jdbc:timesten:{direct|client}:dsn=DSNname;[DSNattributes;]

デフォルトはdirectです。

たとえば、サンプル・データベースへの直接接続を次のように作成します。

String URL = "jdbc:timesten:direct:dsn=sampledb_1122";

接続URLに属性を指定して、DSNの記述に接続属性をプログラム的に設定または上書きすることができます。

接続属性の概要については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のData Manager DSNまたはサーバーDSNの接続属性に関する説明を参照してください。一般的な接続属性に特別な権限は必要ありません。データベースが最初にロードされたときに、最初の接続属性が設定された後、すべての接続で有効になります。インスタンス管理者のみが、データベースをロードして最初の接続属性の設定を変更できます。特定の接続属性(必要な権限を含む)の詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』の接続属性に関する説明を参照してください。

たとえば、LockLevelの一般的な接続属性を1に設定するには、次のようにURLを作成します。

String URL = "jdbc:timesten:direct:dsn=sampledb_1122;LockLevel=1";

データベースへの接続

URLを定義したら、DriverManagerまたはTimesTenDataSourceのいずれかのgetConnection()メソッドを使用し、データベースに接続します。

DriverManager.getConnection()メソッドを使用する場合は、データベースに接続するドライバURLを指定します。

import java.sql.*;
...
Connection conn = DriverManager.getConnection(URL);

TimesTenDataSourceメソッドgetConnection()を使用するには、まずデータ・ソースを作成します。次に、TimesTenDataSourceメソッドsetUrl()を使用してURLを設定し、getConnection()を使用して接続します。

import com.timesten.jdbc.TimesTenDataSource;
import java.sql.*;
...

TimesTenDataSource ds = new TimesTenDataSource();
ds.setUrl("jdbc:timesten:direct:<dsn>");
Connection conn = ds.getConnection();

TimesTenユーザー名およびパスワードは、setUrl()コールのURLのDSNに設定できますが、これを別に設定したり、Oracle Databaseパスワードを設定する(該当する場合)TimesTenDataSourceメソッドもあります。

TimesTenDataSource ds = new TimesTenDataSource();
ds.setUser(myttusername);                    // User name to log in to TimesTen
ds.setPassword(myttpwd);                     // Password to log in to TimesTen
ds.setUrl("jdbc:timesten:direct:<dsn>");
ds.setOraclePassword(myorapwd);              // Password to log in to Oracle DB
Connection conn = ds.getConnection();

DriverManager.getConnection()メソッドまたはds.getConnection()メソッドのいずれかによって、データベースへのハンドルとして利用できるConnectionオブジェクト(この例ではconn)が返されます。DriverManagerメソッドgetConnection()の使用例についてはlevel1デモを、TimesTenDataSourceメソッドgetConnection()の使用例についてはlevel2デモおよびlevel3デモを参照してください。「TimesTen Javaのデモ」を参照してください。

データベースからの切断

データベースにアクセスする必要がなくなった場合、Connectionメソッドclose()をコールし、データベースへの接続をクローズします。

エラーが発生した場合は、データベースから切断する前に、トランザクションをロールバックできます。詳細は、「致命的ではないエラーの処理」および「失敗したトランザクションのロールバック」を参照してください。

直接接続のオープンおよびクローズ

例2-1に、サンプル・データベースへの直接接続を作成し、いくつかのSQLを実行し、その後接続をクローズするためにDriverManagerクラスを使用するアプリケーションの一般的なフレームワークを示します。処理の例については、level1デモを参照してください。(デモについては、「TimesTen Javaのデモ」を参照してください。)

例2-1 接続、SQLの実行、切断

String URL = "jdbc:timesten:dsn=sampledb_1122";
Connection conn = null;

try {
Class.forName("com.timesten.jdbc.TimesTenDriver");
} catch (ClassNotFoundException ex) {
// See "Handling errors"
}

try {
// Open a connection to TimesTen
conn = DriverManager.getConnection(URL);

// Report any SQLWarnings on the connection
// See "Reporting errors and warnings"

// Do SQL operations
// See "Managing TimesTen data" below

// Close the connection to TimesTen
conn.close();

// Handle any errors
} catch (SQLException ex) {
// See "Handling errors"
}

データベースの妥当性の確認

アプリケーションは次のTimesTenConnectionメソッドをコールして、データベースが妥当であるかを検出できます。

boolean isDataStoreValid() throws java.sql.SQLException

データベースが妥当な場合にはtrueが返され、システムまたはアプリケーションの障害などによりデータベースが無効な場合にはfalseが返されます。

接続のアクセス制御

任意のユーザー(インスタンス管理者以外)がデータベースに接続するには、CREATE SESSION権限を付与する必要があります。これはシステム権限であるため、インスタンス管理者、またはADMIN権限を持った者からユーザーに対して、直接またはPUBLICロールを介して付与する必要があります。詳細な説明および例については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のアクセス制御の管理に関する項を参照してください。

JMS/XLA接続を作成し、JMS/XLAの機能を実行するには、CREATE SESSION権限に加え、「アクセス制御がXLAに与える影響」で説明するXLA権限をユーザーに付与する必要があります。

TimesTenデータの管理

この項では、TimesTenデータベースでのデータの操作方法の詳細情報を説明します。内容は次のとおりです。

- 単純なSQL文の実行

- TimesTen結果セットの使用: ヒントおよび制限

- 複数のデータ行のフェッチ

- パラメータのバインドと文の実行

- REF CURSORの使用

- DML RETURNING(RETURNING INTO句)の使用

- ROWIDの使用

- LOBの作業

- データベースに対する変更のコミットまたはロールバック

- 複数スレッドの管理

- Javaのエスケープ構文およびSQLファンクション

単純なSQL文の実行

SQLを使用してデータを管理する方法については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTenデータベースのデータの処理に関する説明を参照してください。この項では、ConnectionインスタンスのcreateStatement()メソッド、およびStatementインスタンスのexecuteUpdate()メソッドまたはexecuteQuery()メソッドを使用して、Javaアプリケーション内でSQL文を実行する方法について説明します。

事前に文が準備されていない場合は、SQL文の特性および返された結果セットに応じて、execute()、executeUpdate()、executeQuery()などのStatementオブジェクトの実行メソッドを使用します。

事前に準備されたSQL文には、PreparedStatementオブジェクトの同じ実行メソッドを使用します。

execute()メソッドは、結果セットがある場合はtrueを返し(SELECTなど)、結果セットがない場合はfalseを返します(INSERT、UPDATE、DELETEなど)。executeUpdate()メソッドは、影響を受ける行数を返します。たとえば、INSERT文を実行すると、executeUpdate()メソッドは挿入された行数を返します。executeQuery()メソッドは結果セットを返すため、(SELECT文の実行時など)結果セットが必要な場合にのみコールする必要があります。

注意:

- TimesTenで生成された結果セットの使用に関する注意事項は、「TimesTen結果セットの使用: ヒントおよび制限」を参照してください。

- アクセス制御権限は、SQLが準備されたとき、およびそのSQL文がデータベースで実行されたときに確認されます。関連する情報は、「アクセス制御のためのTimesTen機能の検討」を参照してください。

例2-2 更新の実行

この例では、StatementオブジェクトでexecuteUpdate()メソッドを使用して、現在のスキーマのcustomer表にデータを挿入するINSERT文を実行します。示されてはいませんが、この接続はオープンされている必要があります。

Connection conn = null;
Statement stmt = null;
...
// [Code to open connection. See "Connect to the database"...]
...
try {
stmt = conn.createStatement();
int numRows = stmt.executeUpdate("insert into customer values"
+ "(40, 'West', 'Big Dish', '123 Signal St.')");
}
catch (SQLException ex) {
...
}

例2-3 問合せの実行

この例では、StatementオブジェクトでexecuteQuery()コールを使用し、現在のスキーマのcustomer表にSELECT文を実行して、返されたjava.sql.ResultSetインスタンスを表示します。

Statement stmt = null;
. . . . . .
try {
ResultSet rs = stmt.executeQuery("select cust_num, region, " +
"name, address from customer");
System.out.println("Fetching result set...");
while (rs.next()) {
System.out.println("\n Customer number: " + rs.getInt(1));
System.out.println(" Region: " + rs.getString(2));
System.out.println(" Name: " + rs.getString(3));
System.out.println(" Address: " + rs.getString(4));
}
}
catch (SQLException ex) {
ex.printStackTrace();
}

TimesTen結果セットの使用: ヒントおよび制限

ResultSetオブジェクトを使用して、問合せ結果を処理します。また、一部のメソッドおよび組込みプロシージャは、ResultSetオブジェクトの形式でTimesTenデータを返します。この項では、TimesTenからのResultSetオブジェクトの使用について説明します。

重要:
TimesTenでは、コミットやロールバックなど、トランザクションを終了する操作は、接続に関連付けられているすべてのカーソルをクローズします。

- TimesTenでは、1つの文で複数のResultSetオブジェクトをオープンすることはできません。また、1つのStatementオブジェクトから、現行結果セットをクローズせずに複数のResultSetオブジェクトを返すことはできません。

- TimesTenでは、保持可能なカーソルはサポートされていません。結果セットの保持可能性(つまり、カーソルのコミット後に、そのカーソルをオープンしたままにできるかどうか)は指定できません。

- ResultSetオブジェクトをスクロールまたは更新できないため、ResultSet.TYPE_SCROLL_SENSITIVEまたはResultSet.CONCUR_UPDATABLEは指定できません。

- ResultSetメソッドclose()を使用して、処理後すぐに結果セットをクローズできます。パフォーマンス上の理由から、これは読取りおよび更新処理で使用される結果セットおよびプール接続で使用される結果セットで特に重要です。

- 基礎となるデータ型が文字列ではない場合、ResultSetメソッドgetString()をコールすると、パフォーマンスの点でコストが高くなります。Javaの文字列は不変的であるため、getString()は、コールされるたびに新しい文字列用に領域を確保する必要があります。したがって、必要な場合を除き、byteやintなどの基本的な数値型の取得にgetString()を使用しないでください。たとえば、整数列の場合、getInt()をコールする方が大幅に高速に処理が実行されます。「ResultSetメソッドgetString()の限定的使用」も参照してください。
また、日付およびタイムスタンプの場合、ResultSetのネイティブ・メソッドgetDate()およびgetTimestamp()の方がgetString()よりもパフォーマンスに優れています。

- getXXX()コールの選択および起動後の必要なデータ変換は、アプリケーション・パフォーマンスに影響を与えます。

- JDBCはConnectionCharacterSet属性の設定を無視します。データはUTF-16エンコードで返されます。

複数のデータ行のフェッチ

複数のデータ行をフェッチすると、コミット読取り分離レベルが設定されたデータベースに接続しているクライアント/サーバー・アプリケーションのパフォーマンスを向上させることができます。

プリフェッチされる行数を指定するには、次の手順を実行します。

- StatementまたはResultSetメソッドsetFetchSize()をコールします。これらのメソッドは標準のJDBCコールですが、1回の実行で効果があるのは1つの文のみであるという制限があります。

- TimesTenConnectionメソッドsetTtPrefetchCount()をコールします。これにより、ある接続に対するすべての文で同じプリフェッチ設定が使用されるように、その接続レベルでのプリフェッチを確立するTimesTenの拡張が有効になります。

この項では、TimesTenで実装されている接続レベルのプリフェッチについて説明します。

注意:
TimesTenのプリフェッチ数を拡張しても、データベースへの直接接続を使用するアプリケーションにとってメリットはありません。

プリフェッチ数を0(ゼロ)に設定すると、TimesTenはデータベースに設定した分離レベルに応じてデフォルトのプリフェッチ数を使用し、プリフェッチ数をその値に設定します。コミット読取り分離レベルでは、デフォルトのプリフェッチの値は5です。シリアライズ可能分離レベルでは、デフォルトは128です。デフォルトのプリフェッチの値はほとんどのアプリケーションに最適な設定です。一般的に、値を高く設定すると、リソースの使用量がわずかに増加しますが、大きい結果セットに対するパフォーマンスは向上する可能性があります。

プリフェッチを無効にするには、プリフェッチ数を1に設定します。

TimesTenConnectionメソッドgetTtPrefetchCount()をコールして、現行のプリフェッチ値を確認します。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

例2-4 プリフェッチ・カウントの設定

次のコードでは、setTtPrefetchCount()コールを使用して、プリフェッチ数を10に設定し、getTtPrefetchCount()コールを使用して、カウント変数のプリフェッチ数を返します。

TimesTenConnection conn =
(TimesTenConnection) DriverManager.getConnection(url);

// set prefetch count to 10 for this connection
conn.setTtPrefetchCount(10);

// Return the prefetch count to the 'count' variable.
int count = conn.getTtPrefetchCount();

パラメータのバインドと文の実行

この項では、SQL文の入力または出力パラメータをバインドする方法について説明します。内容は次のとおりです。

- SQL文の準備および入力パラメータの設定

- 出力および入力/出力パラメータの使用

- SQL文での重複したパラメータのバインド

- PL/SQLでの重複したパラメータのバインド

- 連想配列のバインド

注意:

- Statement、PreparedStatementまたはCallableStatementのメソッドclose()を使用して、使用が終わった文をクローズします。

- TimesTen開発者ガイドで使用される「バインド・パラメータ」という用語(ODBC用語に準拠)は、TimesTenのPL/SQLのマニュアルで使用される「バインド変数」という用語(Oracle Database PL/SQL用語に準拠)と同じです。

SQL文の準備および入力パラメータの設定

複数回実行するSQL文は、ConnectionメソッドprepareStatement()をコールして事前に準備しておく必要があります。最大のパフォーマンスを得るために、パラメータを使用した文を準備します。

次のことに注意してください。

- TimesTenのバインド・メカニズム(アーリー・バインディング)はOracle Databaseのバインド・メカニズム(レイト・バインディング)とは異なります。TimesTenは、問合せの準備の前にデータ型を必要とします。そのため、各バインド・パラメータのデータ型が指定されていないかSQL文から推測できないと、エラーが発生します。たとえば次のような文が、これに該当します。

SELECT 'x' FROM DUAL WHERE ? = ?;

この問題には、たとえば次のように対処できます。

SELECT 'x' from DUAL WHERE CAST(? as VARCHAR2(10)) = CAST(? as VARCHAR2(10));

- デフォルトでは(接続属性PrivateCommands=0の場合)、TimesTenは接続間で準備された文を共有するため、様々な接続での同じ文の後続の準備は非常に迅速に実行されます。

- setXXX()コールの選択および起動前の必要なデータ変換の選択は、アプリケーション・パフォーマンスに影響を与えます。たとえば、時刻、日付およびタイムスタンプでは、PreparedStatementのネイティブ・メソッドsetTime()、setDate()およびsetTimestamp()は、setString()よりもパフォーマンスに優れています。

- アクセス制御権限は、SQLが準備されたとき、およびそのSQL文がデータベースで実行されたときに確認されます。関連する情報は、「アクセス制御のためのTimesTen機能の検討」を参照してください。

- TT_TINYINT列では、TT_TINYINT (0から255)の範囲を完全に実現するために、setByte()のかわりにsetShort()またはsetInt()を使用します。

例2-5 問合せのための準備された文

この例では、PreparedStatementオブジェクトでの基本的なexecuteQuery()コールを示します。これは、準備済のSELECT文を実行して、返された結果セットを表示します。

PreparedStatement pSel = conn.prepareStatement("select cust_num, " +
"region, name, address " +
"from customer" +
"where region = ?");
pSel.setInt(1,1);

try {
ResultSet rs = pSel.executeQuery();

while (rs.next()) {
System.out.println("\n Customer number: " + rs.getInt(1));
System.out.println(" Region: " + rs.getString(2));
System.out.println(" Name: " + rs.getString(3));
System.out.println(" Address: " + rs.getString(4));
}
}
catch (SQLException ex) {
ex.printStackTrace();
}

例2-6 更新のための準備された文

次の例に、4つの別々の文のかわりに、パラメータを使用した単一の文を使用する方法を示します。

値が異なる同様のINSERT文の実行:

Statement.execute("insert into t1 values (1, 2)");
Statement.execute("insert into t1 values (3, 4)");
Statement.execute("insert into t1 values (5, 6)");
Statement.execute("insert into t1 values (7, 8)");

パラメータを使用した単一のINSERT文を準備し、PreparedStatementメソッドsetXXX()を使用して、各文を実行する前に行の値を設定する方がより効率的です。

PreparedStatement pIns = conn.PreparedStatement("insert into t1 values (?,?)");

pIns.setInt(1, 1);
pIns.setInt(2, 2);
pIns.executeUpdate();

pIns.setInt(1, 3);
pIns.setInt(2, 4);
pIns.executeUpdate();

pIns.setInt(1, 5);
pIns.setInt(2, 6);
pIns.executeUpdate();

pIns.setInt(1, 7);
pIns.setInt(2, 8);
pIns.executeUpdate();

conn.commit();
pIns.close();

TimesTenでは、準備された文がコミットされると、自動的に共有されます。たとえば、データベースへの2つ以上の別々の接続が、それぞれ同じ文を、1個、2個、3個、...、n個準備した場合、TimesTenは最初に準備した文を覚えているため、n番目の準備はとても早く返されます。

例2-7 更新および問合せのための準備された文

この例では、INSERT文とSELECT文を準備し、INSERTを2回実行し、SELECTを実行し、返された結果セットを出力します。作業例については、level1デモを参照してください。(デモについては、「TimesTen Javaのデモ」を参照してください。)

Connection conn = null;
...
// [Code to open connection. See "Connect to the database"...]
...

// Disable auto-commit
conn.setAutoCommit(false);

// Report any SQLWarnings on the connection
// See "Reporting errors and warnings"

// Prepare a parameterized INSERT and a SELECT Statement
PreparedStatement pIns =
conn.prepareStatement("insert into customer values (?,?,?,?)");

PreparedStatement pSel = conn.prepareStatement
("select cust_num, region, name, " +
"address from customer");

// Data for first INSERT statement
pIns.setInt(1, 100);
pIns.setString(2, "N");
pIns.setString(3, "Fiberifics");
pIns.setString(4, "123 any street");

// Execute the INSERT statement
pIns.executeUpdate();

// Data for second INSERT statement
pIns.setInt(1, 101);
pIns.setString(2, "N");
pIns.setString(3, "Natural Foods Co.");
pIns.setString(4, "5150 Johnson Rd");

// Execute the INSERT statement
pIns.executeUpdate();

// Commit the inserts
conn.commit();

// Done with INSERTs, so close the prepared statement
pIns.close();

// Report any SQLWarnings on the connection.
reportSQLWarnings(conn.getWarnings());

// Execute the prepared SELECT statement
ResultSet rs = pSel.executeQuery();

System.out.println("Fetching result set...");
while (rs.next()) {
System.out.println("\n Customer number: " + rs.getInt(1));
System.out.println(" Region: " + rs.getString(2));
System.out.println(" Name: " + rs.getString(3));
System.out.println(" Address: " + rs.getString(4));
}

// Close the result set.
rs.close();

// Commit the select - yes selects must be committed too
conn.commit();

// Close the select statement - we're done with it
pSel.close();

例2-8 複数の接続のための準備された文

この例では、3つの接続に対して、パラメータを使用した同一のINSERT文を3つ準備します。接続conn1の最初の準備済INSERTは、TimesTen内部の準備済文キャッシュ内でconn2およびconn3接続と共有され、pIns2およびpIns3の準備操作を加速します。

Connection conn1 = null;
Connection conn2 = null;
Connection conn3 = null;
.....
PreparedStatement pIns1 = conn1.prepareStatement
("insert into t1 values (?,?)");

PreparedStatement pIns2 = conn2.prepareStatement
("insert into t1 values (?,?)");

PreparedStatement pIns3 = conn3.prepareStatement
("insert into t1 values (?,?)");

注意:
結合順序、索引、ロックなど、すべてのオプティマイザ・ヒントは、TimesTenの内部準備済文キャッシュで共有される文と一致している必要があります。また、準備された文が一時表を参照する場合、この文は1つの接続内でのみ共有されます。

出力および入力/出力パラメータの使用

「SQL文の準備および入力パラメータの設定」では、文の準備の方法およびPreparedStatementメソッドを使用した入力パラメータの設定について説明しています。TimesTenでは、PreparedStatementのかわりにjava.sql.CallableStatementを使用する、次の出力および入力/出力パラメータもサポートしています。

1. メソッドregisterOutParameter()を使用して、出力パラメータまたは入力/出力パラメータを登録し、パラメータの位置(文内の位置)およびデータ型を指定します。
これは、CallableStatementインタフェースで指定されている標準のメソッドです。

void registerOutParameter(int parameterIndex, int sqlType, int scale)

ただし、CHAR、VARCHAR、NCHAR、NVARCHAR、BINARYまたはVARBINARYデータに対してこの標準バージョンを使用すると、TimesTenでは、指定可能な最大値を保持するために必要なメモリーを割り当てます。これは、ほとんどの場合で無駄になります。

そのかわりに、最大データ長を指定できるregisterOutParameter()シグネチャが含まれるTimesTenの拡張インタフェースTimesTenCallableStatementを使用します。CHAR、VARCHAR、NCHARおよびNVARCHARについては、長さの単位は文字数になります。BINARYおよびVARBINARYについてはバイトになります。

void registerOutParameter(int paramIndex,
int sqlType,
int ignore, //This parameter is ignored by TimesTen.
int maxLength)

2. 適切なCallableStatementメソッドsetXXX()を使用し(XXXはデータ型を示します)、入力/出力パラメータの入力値を設定します。パラメータの位置およびデータの値を指定します。

3. 適切なCallableStatementメソッドgetXXX()を使用して、出力パラメータまたは入力/出力パラメータの出力値を取得し、パラメータの位置を指定します。

重要:
出力パラメータを処理する前にSQL警告を確認します。警告イベント中には、出力パラメータは定義されません。エラーおよび警告に関する一般的な情報は、「エラー処理」を参照してください。

注意:
TimesTenの場合:

- 名前を使用してパラメータをCallableStatementオブジェクトに渡すことはできません。位置でパラメータを設定する必要があります。SQLのエスケープ構文は使用できません。

- 名前によってパラメータを指定するregisterOutParameter()シグネチャはサポートされていません。位置によってパラメータを指定する必要があります。

- SQL構造型はサポートされていません。

例2-9 コール可能な文での出力パラメータの使用

この例は、コール可能な文での出力パラメータの使用方法を示します。TimesTenCallableStatementインスタンスで、PL/SQLブロックは、新しい給与を計算し、整数で返すファンクションRAISE_SALARYをコールします。Connectionインスタンスをconnとします。(PL/SQLに関する情報は、『Oracle TimesTen In-Memory Database PL/SQL開発者ガイド』を参照してください。)

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Types;
import com.timesten.jdbc.TimesTenCallableStatement;
...
// Prepare to call a PL/SQL stored procedure RAISE_SALARY
CallableStatement cstmt = conn.prepareCall
("BEGIN :newSalary := RAISE_SALARY(:name, :inc); end;");

// Declare that the first param (newSalary) is a return (output) value of type int
cstmt.registerOutParameter(1, Types.INTEGER);

// Raise Leslie's salary by $2000 (she wanted $3000 but we held firm)
cstmt.setString(2, "LESLIE"); // name argument (type String) is the second param
cstmt.setInt(3, 2000); // raise argument (type int) is the third param

// Do the raise
cstmt.execute();

// Check warnings. If there are warnings, output parameter values are undefined.
SQLWarning wn;
boolean warningFlag = false;
if ((wn = cstmt.getWarnings() ) != null) {
do {
warningFlag = true;
System.out.println(wn);
wn = wn.getNextWarning();
} while(wn != null);
}

// Get the new salary back
if (!warningFlag) {
int new_salary = cstmt.getInt(1);
System.out.println("The new salary is: " + new_salary);
}

// Close the statement and connection
cstmt.close();
conn.close();
...

SQL文で重複パラメータをバインドする

TimesTenでは、SQL文で重複したパラメータをバインドするための2つの異なるモードをサポートしています。

- Oracleモード: 同じパラメータ名の複数のインスタンスは別のパラメータとして認識されます。

- 以前のリリースと同様の従来のTimesTenモード: 同じパラメータ名が複数回出現する場合、同じパラメータが複数回出現しているとみなされます。

DuplicateBindMode TimesTen一般接続属性を使用すると、目的のモードを選択できます。DuplicateBindMode=0(デフォルト)はOracleモードで、 DuplicateBindMode=1はTimesTenモードです。この属性は一般接続属性であるため、同じデータベースに対する複数の接続でそれぞれ異なる値を使用できます。この属性の詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のDuplicateBindModeに関する項を参照してください。

この項の後半では、各モードの詳細を示します。次の問合せについて考えてみます。

SELECT * FROM employees
WHERE employee_id < :a AND manager_id > :a AND salary < :b;

注意:
この説明は、(PL/SQLなどを介してではなく)JDBCから直接発行されたSQL文にのみ該当します。

重複パラメータに対するOracleモード

Oracleモード(DuplicateBindMode=0)では、1つのSQL文に含まれる同じパラメータ名の複数回の出現は異なるパラメータとみなされます。パラメータ位置番号を割り当てるとき、名前の重複は考慮せずに各パラメータの出現に番号が割り当てられます。アプリケーションでは、最低でも、各パラメータ名の最初の出現に値がバインドされます。そのパラメータ名が次回出現した場合、アプリケーションでは次のいずれかが実行されます。

- その出現に対して別の値をバインドします。

- そのパラメータの出現をバインドしないままにします。この場合は、最初の出現と同じ値をとります。

どちらの場合でも、それぞれの出現は、異なるパラメータ位置番号を持っています。

前述のSQL文で、aの2度目の出現に対して別の値を使用するには、次のようにします。

pstmt.setXXX(1, ...); /* first occurrence of :a */
pstmt.setXXX(2, ...); /* second occurrence of :a */
pstmt.setXXX(3, ...); /* occurrence of :b */

両方のaの出現に対して同じ値を使用するには、次のようにします。

pstmt.setXXX(1, ...); /* both occurrences of :a */
pstmt.setXXX(3, ...); /* occurrence of :b */

いずれの場合も、パラメータbは位置3にあるとみなされます。

重複パラメータに対するTimesTenモード

TimesTenモード(DuplicateBindMode=1)では、重複したパラメータを含むSQL文は、異なるパラメータ名のみが別のパラメータとしてみなされるように解析されます。アプリケーションでは一意のパラメータごとにのみ1つの値がバインドされ、一意でないパラメータはバインドされません。

バインドは、パラメータ名が最初に出現した位置に基づいて行われます。以降に出現するパラメータ名は、同じ値にバインドされ、パラメータ位置番号は与えられません。

前述のSQL文では、aの2つの出現が単一のパラメータとみなされるため、別々にバインドすることはできません。

pstmt.setXXX(1, ...); /* both occurrences of :a */
pstmt.setXXX(2, ...); /* occurrence of :b */

TimesTenモードでは、パラメータbは位置3ではなく、位置2にあるとみなされることに注意してください。

PL/SQL文で重複パラメータをバインドする

前述の説明は、独自のセマンティクスがあるPL/SQLには該当しません。PL/SQLでは、一意の各パラメータ名に値をバインドします。たとえば、次のブロックを実行するアプリケーションは、:aに対応する1つのパラメータのみをバインドします。

DECLARE
x NUMBER;
y NUMBER;
BEGIN
x:=:a;
y:=:a;
END;

次のブロックを実行するアプリケーションでも、1つのパラメータのみをバインドします。

BEGIN
INSERT INTO tab1 VALUES(:a, :a);
END

これは、次のCALL文でも同様です。

...CALL proc(:a, :a)...

次のブロックを実行するアプリケーションは、2つのパラメータ(パラメータ#1に:a、パラメータ#2に:b)をバインドします。各INSERT文の2番目のパラメータは、次のように、最初のINSERT文の最初のパラメータと同じ値を使用します。

BEGIN
INSERT INTO tab1 VALUES(:a, :a);
INSERT INTO tab1 VALUES(:b, :a);
END

連想配列のバインド

TimesTen JDBCでは、TimesTen PL/SQLへのIN、OUTまたはIN OUTバインド・パラメータである、以前の索引付き表またはPL/SQL表と呼ばれていた連想配列バインドをサポートしています。連想配列では、JDBCアプリケーションとデータベース間で効率的にデータの配列を渡すことを可能にします。

連想配列とは、キーと値のペアのセットです。TimesTenの連想配列バインド(PL/SQL内のみに連想配列の使用は限定されません)では、キーまたは索引は整数(BINARY_INTEGERまたはPLS_INTEGER)である必要があります。値は、同じデータ型の単純なスカラー値である必要があります。たとえば、部署番号ごとに索引付された部署のマネージャの配列を作成できます。索引は、作成された順序ではなく、ソートされた順序で格納されます。

次の例のように、PL/SQLで連想配列型を宣言した後、連想配列を宣言します(INDEX BYに注意してください)。

declare
TYPE VARCHARARRTYP IS TABLE OF VARCHAR2(30) INDEX BY BINARY_INTEGER;
x VARCHARARRTYP;
...

Oracle TimesTen In-Memory Database PL/SQL開発者ガイドのアプリケーションからの連想配列の使用に関する説明も参照してください。

Javaで連想配列をバインドする場合、配列の型とできるだけ近いJavaの型を使用すると最適なパフォーマンスが得られます。ただし、TimesTenでは、次のいくつかの単純な入力時の変換をサポートしています。

- 文字列は整数または浮動小数点に変換できます。

- 文字列がTimesTenのDATE(YYYY-MM-DD HH:MI:SS)の書式に従っている場合、文字列をDATEデータに変換できます。

注意:
TimesTenには次の制限があることに注意してください。

- 連想配列のバインドでは、LOB、REF CURSOR、TIMESTAMP、ROWIDの型はサポートされていません。

- パススルー文では連想配列のバインドはサポートされていません。

- TimesTenのJDBCでは、一般的な配列のバルク・バインドはサポートされていません。VARRAYおよびネストされた表は、バインド・パラメータとしてサポートされていません。

- 連想配列パラメータは、JDBCのバッチの実行ではサポートされていません(「バッチ実行にパラメータの配列を使用」を参照してください)。

TimesTenには、TimesTenPreparedStatementとTimesTenCallableStatementのインタフェースを介して連想配列のバインドをサポートする、次で説明する拡張が用意されています。ここで説明するメソッドの詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

TimesTenでは、PL/SQLのINまたはIN OUTパラメータである連想配列で入力連想配列を設定するために、(INパラメータ用に)TimesTenPreparedStatementインタフェースで、また(IN OUTパラメータ用に)TimesTenCallableStatementインタフェースで、setPlsqlIndexTable()メソッドを用意しています。

- void setPlsqlIndexTable(int paramIndex, java.lang.Object arrayData, int maxLen, int curLen, int elemSqlType, int elemMaxLen)
次のように指定します。

- paramIndex: (1で開始する)PL/SQL文内のパラメータの位置

- arrayData: バインドする値の配列(これはint[]などプリミティブ型の配列またはBigDecimal[]などオブジェクト型の配列が許可されます)

- maxLen: 連想配列内の要素の最大数(TimesTenでは、curLenと同じにする必要があります)

- curLen: 連想配列内に現在ある要素の実際の数(TimesTenではmaxLenと同じである必要があります)

- elemSqlType: java.sql.Typesと一致する連想配列の要素の型(Types.DOUBLEなど)

- elemMaxLen: CHAR、VARCHAR、BINARYまたはVARBINARYの連想配列で、各要素の最大長(CHARまたはVARCHARの連想配列では文字列、BINARYまたはVARBINARYの連想配列ではバイトです)

次に例を示します(TimesTenPreparedStatementインスタンスpstmtを仮定)。

int maxLen = 3;
int curLen = 3;
// Numeric field can be set with int, float, double types.
// elemMaxLen is set to 0 for numeric types and is ignored.
// elemMaxLen is specified for VARCHAR types.
pstmt.setPlsqlIndexTable
(1, new int[]{4, 5, 6}, maxLen, curLen, Types.NUMERIC, 0);
pstmt.setPlsqlIndexTable
(2, new String[]{"Batch1234567890", "2", "3"}, maxLen, curLen,
Types.VARCHAR, 15);
pstmt.execute();

注意:

- elemMaxLenパラメータは、CHAR、VARCHAR、BINARYまたはVARBINARY以外の型では無視されます。それらのすべての型では、値に0を使用すると、バインドされているデータの実際の長さに基づいて各要素の最大長を設定するようドライバに指示できます。elemMaxLenが正の値に設定され、実際のデータ長がelemMaxLenより大きい場合、データは常にelemMaxLenの長さに切り捨てられます。

- curLenが連想配列内の実際の要素数より小さい場合、curLenの要素のみがバインドされます。

TimesTenでは、PL/SQLのOUTまたはIN OUTパラメータである連想配列用に、出力連想配列を登録するregisterIndexTableOutParameter()と出力連想配列を取得するgetPlsqlIndexTable()の2つのメソッドをTimesTenCallableStatementインタフェースに用意しています。getPlsqlIndexTable()には、連想配列の要素がSQL型であると仮定しJDBCのデフォルトのJavaオブジェクト型を使用するものと、型を指定する2つのシグネチャがあります。

- void registerIndexTableOutParameter(int paramIndex, int maxLen, int elemSqlType, int elemMaxLen)
次のように指定します。

- paramIndex: (1で開始する)PL/SQL文内のパラメータの位置

- maxLen: 連想配列に含めることが可能な要素の最大数

- elemSqlType: java.sql.Typesと一致する連想配列の要素の型(Types.DOUBLEなど)

- elemMaxLen: CHAR、VARCHAR、BINARYまたはVARBINARYの連想配列で、各要素の最大長(CHARまたはVARCHARの連想配列では文字列、BINARYまたはVARBINARYの連想配列ではバイトです)

注意:
elemMaxLenの値が0以下の場合、データ型の最大長が使用されます。

- java.lang.Object getPlsqlIndexTable(int paramIndex)
このメソッド・シグネチャでは、返された連想配列の型が、取得したSQL型のデータのJDBCでのデフォルトのマッピングになります。(1で開始する)PL/SQL文内のパラメータの位置を指定します。デフォルト・マッピングについては、表2-3を参照してください。

- java.lang.Object getPlsqlIndexTable(int paramIndex, java.lang.Class primitiveType)
このメソッド・シグネチャでは、パラメータの位置の指定に加え、java.sql.Typesと一致する返される連想配列の希望の型を指定します(Types.DOUBLEなど)。これはプリミティブ型である必要があります。

表2-3 連想配列要素のJDBCのデフォルト・マッピング

戻り値の型

SQLの型

Integer[]

TINYINT、SMALLINT、TT_INTEGER

Long[]

BIGINT

BigDecimal[]

NUMBER

Float[]

BINARY_FLOAT

Double[]

BINARY_DOUBLE

String[]

CHAR、VARCHAR、NCHAR、NVARCHAR

Timestamp[]

DATE

次のコード部分では、IN OUTパラメータの内容を設定、登録および取得する方法を示しています(connは接続、cstmtはTimesTenCallableStatementインスタンスを想定しています)。

int maxLen = 3;
int curLen = 3;
anonBlock = "begin AssocArrayEx_inoutproc(:o1); end;";
cstmt = (TimesTenCallableStatement) conn.prepareCall(anonBlock);
cstmt.setPlsqlIndexTable
(1, new Integer[] {1,2,3}, maxLen, curLen, Types.NUMERIC, 0);
cstmt.registerIndexTableOutParameter(1, maxLen, Types.NUMERIC, 0);
cstmt.execute();

int[]  ret = (int [])cstmt.getPlsqlIndexTable(1, Integer.TYPE);
cstmt.execute();

例2-10 連想配列のバインド

連想配列のバインドのメカニズムを示すより完全な例を次に示します。

TimesTenCallableStatement cstmt = null;
try {
// Prepare procedure with associative array in parameter
cstmt = (TimesTenCallableStatement)
conn.prepareCall("begin AssociativeArray_proc(:name, :inc); end;");

// Set up input array and length
String[] name = {"George", "John", "Thomas", "James", "Bill"};
Integer[] salaryInc = {10000, null, 5000, 8000, 9007};
int currentLen = name.length;
int maxLen = currentLen;

// Use elemMaxLen for variable length data types such as
// Types.VARCHAR, Types.CHAR.
int elemMaxLen = 32;

// set input parameter, name as a VARCHAR
cstmt.setPlsqlIndexTable
(1, name, maxLen, currentLen, Types.VARCHAR, elemMaxLen);
// set input parameter, salaryInc as a number
cstmt.setPlsqlIndexTable
(2, salaryInc, maxLen, currentLen, Types.NUMERIC, 0);

REF CURSORの使用

REF CURSORはPL/SQLの概念で、PL/SQLとアプリケーション間で受け渡しされるSQL結果セット上のカーソルに対するハンドルです。TimesTenでは、PL/SQL内でカーソルをオープンできるため、そのREF CURSORをアプリケーションに渡して結果セットを処理することができます。

アプリケーションは、次のように、REF CURSOR OUTパラメータを受け取ることができます。

1. 型TimesTenTypes.CURSOR(TimesTen型拡張)としてREF CURSOR OUTパラメータを登録すると、REF CURSORのパラメータ位置(文内の位置)も指定されます。

2. TimesTenCallableStatementインタフェース(TimesTen JDBC拡張の1つ)で定義されたgetCursor()メソッドを使用してREF CURSORを取得し、REF CURSORのパラメータ位置を指定します。getCursor()メソッドは他のgetXXX()メソッドと同様に使用され、ResultSetインスタンスを返します。

APIの詳細は、Oracle TimesTen In-Memory Database JDBC拡張Java APIリファレンスを参照してください。REF CURSORの詳細は、『Oracle TimesTen In-Memory Database PL/SQL開発者ガイド』のPL/SQL REF CURSORに関する説明を参照してください。

重要:
PL/SQLとアプリケーションの間でREF CURSORが受渡しされる場合、TimesTenでは、PL/SQLからアプリケーションへのOUT REF CURSORのみと、REF CURSORを1つのみ返す文をサポートしています。

次の例でこれを説明します。

例2-11 REF CURSORの使用

この例は、コール可能な文でのREF CURSORの使用方法を示します。PL/SQLブロックは、CallableStatementインスタンスでカーソルをオープンし、問合せを実行します。TimesTenCallableStatementメソッドgetCursor()は、カーソルを戻すために使用され、そのカーソルはTimesTenTypes.CURSORとして登録されます。

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import com.timesten.jdbc.TimesTenCallableStatement;
import com.timesten.jdbc.TimesTenTypes;
...
Connection conn = null;
CallableStatement cstmt = null;
ResultSet cursor;
...
// Use a PL/SQL block to open the cursor.
cstmt = conn.prepareCall
(" begin open :x for select tblname,tblowner from tables; end;");
cstmt.registerOutParameter(1, TimesTenTypes.CURSOR);
cstmt.execute();
cursor = ((TimesTenCallableStatement)cstmt).getCursor(1);

// Use the cursor as you would any other ResultSet object.
while(cursor.next()){
System.out.println(cursor.getString(1));
}

// Close the cursor, statement, and connection.
cursor.close();
cstmt.close();
conn.close();
...

注意:
ループ内に様々なパラメータ値があるコール可能な文を評価する場合、ループの終了時には毎回カーソルをクローズする必要があります。文を準備した後にループにパラメータを設定し、文を実行し、カーソルを処理し、カーソルをクローズするのが標準的な使用法です。

DML RETURNING(RETURNING INTO句)の使用

DML RETURNINGと呼ばれるRETURNING INTO句をINSERT、UPDATEまたはDELETE文で使用すると、処理の影響を受けた行の特定の項目を返すことができます。これにより、たとえば処理によって影響を受けたものを確認する場合などで、続くSELECT文および個々のラウンド・トリップが不要になります。

TimesTenでは、DML RETURNINGは、単一行の操作から項目を戻すのみです。この句では、項目を出力パラメータのリストに返します。

TimesTenPreparedStatement(標準PreparedStatementインタフェースの拡張)は、DML RETURNINGをサポートします。TimesTenPreparedStatementメソッドregisterReturnParameter()を使用して、戻りパラメータを登録します。

void registerReturnParameter(int paramIndex, int sqlType)

「出力および入力/出力パラメータの使用」で説明したregisterOutParameter()メソッドと同様に、このメソッドには、CHAR、VARCHAR、NCHAR、NVARCHAR、BINARYまたはVARBINARYのデータにオプションで最大サイズを指定できるシグネチャがあります。これにより、TimesTenが非効率に設定可能な最大のメモリー値を割り当ててしまう可能性が回避されます。CHAR、VARCHAR、NCHARおよびNVARCHARのサイズ単位は、文字数です。BINARYおよびVARBINARYについてはバイトになります。

void registerReturnParameter(int paramIndex, int sqlType, int maxSize)

TimesTenPreparedStatementメソッドgetReturnResultSet()を使用して戻りパラメータを取得し、ResultSetインスタンスを返します。

TimesTen JDBCでRETURNING INTOを使用する場合は、次の制限に注意してください。

- getReturnResultSet()メソッドは2回以上実行しないでください。実行すると、動作は不確定です。

- getReturnResultSet()が返す結果セットは、ResultSetMetaDataをサポートしていません。

- getReturnResultSet()が返す結果セットは、getCharacterStream()などのストリーミング・メソッドをサポートしていません。

- DML RETURNINGをサポートするバッチはありません。

ここで説明するTimesTenのJDBCクラス、インタフェース、メソッドの詳細は、Oracle TimesTen In-Memory Database JDBC拡張Java APIリファレンスを参照してください。

Oracle TimesTen In-Memory Database SQLリファレンスのINSERT、UPDATEおよびDELETEに関する説明内には、TimesTenのRETURNING INTO句のSQL構文および制限についての説明があります。

DML RETURNINGに関する一般的な情報は、『Oracle Database PL/SQL言語リファレンス』のRETURNING INTO句に関する説明を参照してください。

重要:
TimesTenの準備済の文の実行後は、SQL警告を確認してください。警告イベント中には、出力パラメータは定義されません。エラーおよび警告に関する一般的な情報は、「エラー処理」を参照してください。

例2-12 DML RETURNING

この例では、TimesTenPreparedStatementインスタンスでDML RETURNINGを使用する方法を示しています。挿入された行の名前および経過時間を返します。

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.Types;
import com.timesten.jdbc.TimesTenPreparedStatement;

Connection conn = null;
...

// Insert into a table and return results
TimesTenPreparedStatement pstmt =
(TimesTenPreparedStatement)conn.prepareStatement
("insert into tab1 values(?,?) returning name, age into ?,?");

// Populate table
pstmt.setString(1,"John Doe");
pstmt.setInt(2, 65);

/* register returned parameter
* in this case the maximum size of name is 100 chars
*/
pstmt.registerReturnParameter(3, Types.VARCHAR, 100);
pstmt.registerReturnParameter(4, Types.INTEGER);

// process the DML returning statement
int count = pstmt.executeUpdate();

/* Check warnings; if there are warnings, values of DML RETURNING INTO
parameters are undefined. */
SQLWarning wn;
boolean warningFlag = false;
if ((wn = pstmt.getWarnings() ) != null) {
do {
warningFlag = true;
System.out.println(wn);
wn = wn.getNextWarning();
} while(wn != null);
}

if (!warningFlag) {
if (count>0)
{
ResultSet rset = pstmt.getReturnResultSet(); //rset not null, not empty
while(rset.next())
{
String name = rset.getString(1);
int age = rset.getInt(2);
System.out.println("Name " + name + " age " + age);
}
}
}

ROWIDの使用

各行には、rowidと呼ばれる行の一意の識別子があります。アプリケーションは、行のROWIDをROWID擬似列から取得できます。ROWID値はバイナリまたは文字形式で表現され、12バイトのバイナリ形式および18バイトの文字形式で表されます。

TimesTenでは、Java 6用に、java.sql.RowIdインタフェースとTypes.ROWID型をサポートしています。

次のいずれかのResultSetメソッドを使用して、ROWIDを取得できます。

- byte[] getBytes(int columnIndex)

- String getString(int columnIndex)

- Object getObject(int columnIndex)
Java 5.0では、Stringオブジェクトが返されます。Java 6では、RowIdオブジェクトが返されます。

次のいずれかのPreparedStatementメソッドを使用して、ROWIDを設定できます。

- setBytes(int parameterIndex, byte[] x)

- setString(int parameterIndex, String x)

- setRowId(int parameterIndex, RowId x)(Java 6のみ)

- setObject(int parameterIndex, Object x)
Java 5.0では、Stringオブジェクトを取ります。Java 6では、StringまたはRowIdオブジェクトを取ります。

注意:
getBytes()またはsetBytes()を、PL/SQLパラメータまたはパススルー・パラメータ(TimesTen Application-Tier Database Cacheの使用時にOracle Databaseに渡すパラメータ)になるROWIDパラメータに使用できません。RowIdオブジェクト(Java 6のみ)またはStringオブジェクトには、getString()およびsetString()またはgetObject()およびsetObject()を使用してください。

アプリケーションでは、SQL文のWHERE句などで、一重引用符で囲んだCHAR定数としてリテラルのROWID値を指定できます。

使用法およびライフサイクルを含むrowidおよびROWIDデータ型の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』のROWIDデータ型およびROWIDに関する説明を参照してください。

注意:
TimesTenでは、PL/SQL型UROWIDをサポートしていません。

LOBの作業

TimesTenでは、LOB(ラージ・オブジェクト)をサポートしています(具体的には、CLOB(Character LOB)、NCLOB(National Character LOB、Java 6のみ)およびBLOB(Binary LOB))。

この項では、LOBの概要およびLOBのJDBCでの使用について、次の内容で説明します。

- LOBの概要

- JDBCでのLOB

- TimesTenのLOBとOracle DatabaseのLOBの違い

- LOBファクトリ・メソッド

- LOBのgetterメソッドとsetterメソッド

- TimesTenのLOBインタフェース・メソッド

- LOBのプリフェッチ

- パススルーLOB

注意:

- データベースのキャラクタ・セットがTIMESTEN8の場合、TimesTenではCLOBをサポートしません。

- この項では、Java 5.0およびJava 6の両方におけるLOBのサポートについて説明します。ただし、TimesTenではJava 6を使用することを推奨します。こちらの方がより標準的で、完全な実装となります。具体的には、Java 5.0ではNCLOBをサポートしていません。

次の情報も参照できます。

- TimesTenにおけるLOBの詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』のLOBのデータ型に関する説明を参照してください。

- LOBを使用したプログラミングの全般的情報については、Oracle Database SecureFilesおよびラージ・オブジェクト開発者ガイド(TimesTenでの機能には限定されません)を参照してください。

LOBの概要

LOBとは、ラージ・バイナリ・オブジェクト(BLOB)または文字オブジェクト(CLOBまたはNCLOB)です。TimesTenでは、BLOBの最大サイズは16 MBで、CLOBまたはNCLOBは最大4 MBになります。記載がないかぎり、基本的にTimesTenのLOBはOracle Databaseでの場合と同様に機能します。(「TimesTenのLOBとOracle DatabaseのLOBの違い」を参照してください)。

LOBは永続する場合も一時的である場合もあります。永続LOBは、データベースのLOB列に存在します。一時LOBはアプリケーション内のみに存在します。一時LOBは、TimesTenによって黙示で作成される場合もあります。たとえば、SELECT文によって追加の文字列と連結されたLOBが選択される場合、連結データを含むようTimesTenでは一時LOBを作成します。

JDBCでのLOB

JDBCでは、LOBオブジェクト(Blob、ClobまたはNClobインスタンス)には、データ自体ではなくLOBデータへの論理ポインタがLOBオブジェクトに含まれることを意味するSQL LOBロケータ(BLOB、CLOBまたはNCLOB)を使用して実装されます。

重要:

- トランザクションが終了すると、TimesTenではLOBオブジェクトは無効になるので、自動コミットを有効にして使用することはできません。LOBが無効になったことを示すエラーが通知されます。

- APIを介したLOBロケータを使用するLOB操作では、TimesTenの一時領域が使用されます。このような操作が頻繁に行われる場合には、TimesTenの一時データ領域サイズの拡大が必要になることがあります。詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のTempSizeに関する説明を参照してください。

アプリケーションは、JDBC APIを使用して、アプリケーション内で使用するために一時LOBを明示的にインスタンス化でき、処理が終了したらLOBを解放できます。一時LOBは、TimesTenの一時データ領域に保存されます。

永続LOBを更新する場合、トランザクションで、LOBを含む行の排他ロックを取得する必要があります。これは、LOBをSELECT ... FOR UPDATE文で選択することによって実現できます。これによって、ロケータが書込み可能になります。単純なSELECT文では、ロケータは読取り専用となります。読取り専用ロケータと書込み可能ロケータは次のように動作します。

- 読取り専用ロケータは、存続期間中、LOBを選択したときのコンテンツのみを参照する、一貫して読み取りを行うものとなります。これには、LOBが選択される前、同じトランザクションでLOBに対して実行したすべてのコミットされていない更新が含まれることに注意してください。

- 書込み可能ロケータは、ロケータを介した書込みのたびに、データベースの最新データで更新されます。したがって、書込みはLOBの最新データに対して行われます(これには、他のロケータを介して実行された更新も含みます)。

次に、同じLOBに対する2つの書込み可能ロケータの詳しい動作例を示します。

1. LOB列にXYが含まれます。

2. 更新するために、ロケータL1を選択します。

3. 更新するために、ロケータL2を選択します。

4. オフセット1でL1を介し、Zを書き込みます。

5. ロケータL1を介して読み取ります。これによって、ZYが返されます。

6. ロケータL2を介して読み取ります。L2は書込みに使用されるまで、一貫して読み取りを行うため、これによってXYが返されます。

7. オフセット2でL2を介し、Wを書き込みます。

8. ロケータL2を介して読み取ります。これによって、ZWが返されます。前の手順の書込みの前に、ロケータは最新のデータ(ZY)で上書きされました。

TimesTenのLOBとOracle DatabaseのLOBの違い

次のことに注意してください。

- TimesTenのLOB実装とOracle Database実装の主な違いは、TimesTenでは、トランザクションの終了後、LOBオブジェクトが無効になるということです。明示的か暗黙的かにかかわらず、コミットまたはロールバック後、すべてのLOBオブジェクトは無効になります。これには、Oracle Databaseの動作での、あらゆる自動コミット後、またはTimesTenのDDLCommitBehaviorが0(デフォルト)に設定されている場合のあらゆるDDL文後も含まれます。

- TimesTenでは、BFILE、SecureFile、LOBの配列の読取りおよび書込みまたはLOBのコールバック・ファンクションをサポートしていません。

- TimesTenでは、LOBの連想配列のバインドはサポートしていません。

- TimesTenでは、LOBのバッチ処理はサポートしていません。

- BLOBに関して、TimesTenの16進リテラルの使用法に違いがあります。詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』の定数のHexadecimalLiteralに関する説明を参照してください。

LOBファクトリ・メソッド

TimesTenでは、Java 6の標準のConnectionメソッドのcreateBlob()、createClob()およびcreateNClob()をサポートしています。

標準のLOBファクトリ・メソッドがないJava 5.0環境(非推奨)では、TimesTenの拡張のTimesTenConnectionインタフェースにより、次が規定されています。

- createBLOB()

- createCLOB()

Java 5.0では、NCLOBをサポートしていません。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

重要:
TimesTenでは、LOBオブジェクトを作成すると、まだ進行中でない場合は、データベース・トランザクションが作成されます。コミットまたはロールバックを実行し、トランザクションをクローズする必要があります。

LOBのgetterメソッドとsetterメソッド

LOBには、他のデータ型の場合と同様に、標準のjava.sql.ResultSet、PreparedStatementおよびCallableStatementインタフェースで定義するgetterメソッドおよびsetterメソッドを介してアクセスできます。次の適切なgetXXX()メソッドを使用しLOBの結果または出力パラメータを取得するか、setXXX()メソッドを使用しLOB入力パラメータをバインドします。

- ResultSet getterメソッド: 列名または列索引のいずれかに基づいてLOBに取得を指定する、getBlob()メソッド、getClob()メソッドおよびgetNClob()メソッド(Java 6のみ)があります。
Blob、ClobまたはNClob(Java 6のみ)オブジェクトを取得するgetObject()も使用できます。

- PreparedStatement setterメソッド: Blob、ClobまたはNClobインスタンスとパラメータ索引を入力し、入力パラメータをバインドする、setBlob()メソッド、setClob()メソッドおよびsetNClob()メソッド(Java 6のみ)があります。
Blob、ClobまたはNClob入力パラメータをバインドするsetObject()も使用できます。

また、Blobインスタンスのかわりに、InputStreamインスタンスまたはInputStreamインスタンスと長さを指定するsetBlob()メソッドもあります。

setClob()およびsetNClob()メソッドでは、ClobまたはNClobインスタンスのかわりに、ReaderインスタンスまたはReaderインスタンスと長さを指定します。

- CallableStatement getterメソッド: パラメータ名またはパラメータ索引のいずれかに基づいてLOB出力パラメータを取得するgetBlob()メソッド、getClob()メソッドおよびgetNClob()メソッド(Java 6のみ)があります。
Blob、ClobまたはNClob(Java 6のみ)出力パラメータを取得するgetObject()も使用できます。

また、CallableStatementオブジェクトから出力パラメータを登録する必要もあります。registerOutParameter()メソッドでは、パラメータ索引とともにTypes.BLOB、Types.CLOBまたはTypes.NCLOBのSQL型を取ります。

- CallableStatement setterメソッド: これは、PreparedStatement setterメソッドと同一です(継承されます)。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

TimesTenのLOBインタフェース・メソッド

Blobインスタンスをcom.timesten.jdbc.TimesTenBlobに、Clobインスタンスをcom.timesten.jdbc.TimesTenClobに、NClobインスタンスをcom.timesten.jdbc.TimesTenNClobにキャストできます。これらのインタフェースでは、java.sql.Blob、ClobおよびNClobインタフェースで指定するメソッドをサポートしています。

Blobの機能の概要は、次のとおりです。

- TimesTenの拡張であるisPassthrough()メソッドは、BLOBがOracle DatabaseからのパススルーLOBであるかどうかを示します。

- アプリケーションが処理を完了したら、Blobリソースを解放します。
注意: free()メソッドはJava 5.0には含まれませんが、TimesTenの拡張として提供されます。これはJava 6では標準です。

- BLOB値をバイナリ・ストリームとして取得します。一部または全部を取得するメソッドがあります。
注意: getBinaryStream(pos,length)シグネチャはJava 5.0には含まれませんが、TimesTenの拡張として提供されます。これはJava 6では標準です。

- バイト配列として、BLOB値の全部または一部を取得します。

- BLOBのバイト数を戻します。

- BLOBへのバイナリ・データの書込み(指定した位置から開始)に使用するストリームを取得します。これは既存のデータを上書きします。

- BLOBに書き込むバイトの配列を指定し(指定した位置から開始)、書き込んだバイト数を戻します。これは既存のデータを上書きします。配列の全部または一部を書き込むメソッドがあります。

- 指定した長さにBLOBを切り捨てます。

ClobおよびNClob(Java 6のみ)の機能の概要は、次のとおりです。

- TimesTenの拡張であるisPassthrough()メソッドは、CLOBまたはNCLOBがOracle DatabaseからのパススルーLOBであるかどうかを示します。

- アプリケーションが処理を終了したら、ClobまたはNClobリソースを解放します。
注意: free()メソッドはJava 5.0には含まれませんが、TimesTenの拡張として提供されます。これはJava 6では標準です。

- CLOBまたはNCLOBをASCIIストリームとして取得します。
注意: getCharacterStream(pos,length)シグネチャはJava 5.0には含まれませんが、TimesTenの拡張として提供されます。これはJava 6では標準です。

- CLOBまたはNCLOBをjava.io.Readerオブジェクト(または文字のストリーム)として取得します。一部または全部を取得するメソッドがあります。

- CLOBまたはNCLOB内の指定したサブストリングのコピーを、指定の最大長まで(指定した位置から開始して)取得します。

- CLOBまたはNCLOBの文字数を戻します。

- CLOBまたはNCLOBへのASCII文字の書込み(指定した位置から開始)に使用するストリームを取得します。これは既存のデータを上書きします。

- CLOBまたはNCLOBに書き込む(指定した位置から開始)、Java String値を指定します。これは既存のデータを上書きします。String値の全部または一部を書き込むメソッドがあります。

- 指定した長さにCLOBまたはNCLOBを切り捨てます。

注意:

- LOBにデータを書き込むメソッドの場合、書き込まれるデータよりも少ない領域しか指定した位置以降にLOBにない場合を除き、LOBのサイズは変わりません。その場合、データが収まるようLOBのサイズが拡張されます。

- LOBの書込みを指定した位置の値が、LOBの長さに1を足したものより大きい場合の動作は定義されていません。

- InputStreamまたはReaderオブジェクト内のデータ量にかかわらず、メソッド・コールで使用されるバッファ長が0のとき、InputStreamまたはReaderオブジェクトのread()メソッドでは0(ゼロ)が返されます。したがって、SQL EMPTY_CLOB()ファンクションを使用して入力した場合のように、CLOBの長さが0のとき、次のような使用は問題になることがあります。

java.io.Reader r = myclob.getCharacterStream();
char[] buf = new char[myclob.length()]; //buf for r.read() call

通常、read()をコールして、ストリームの最後に達すると-1が返されます。ただし、前の例では-1が返されることはありません。InputStreamを返すBLOB getBinaryStream()メソッド、InputStreamを返すCLOB getAsciiStream()メソッド、Readerを返すCLOB getCharacterStream()メソッドによって返されるストリームを使用する場合は、これに注意してください。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

LOBのプリフェッチ

クライアント/サーバー接続でのサーバーへのラウンドトリップを減らすために、データベースからLOBをフェッチするとき、デフォルトでLOBのプリフェッチが有効になっています。プリフェッチのデフォルト・サイズは、BLOBの場合は4,000バイトで、CLOBまたはNCLOBの場合は4,000文字です。

TimesTenConnectionプロパティCONNECTION_PROPERTY_DEFAULT_LOB_PREFETCH_SIZEを使用すると、デフォルト値とは異なる値を接続のすべての文に適用するよう設定できます。値-1を使用すると、その接続ではデフォルトでLOBのプリフェッチが無効になり、0(ゼロ)を使用するとデフォルトでメタデータのみのLOBのプリフェッチが有効になり、0より大きい任意の値を指定すると、フェッチ操作時にLOBロケータとともに、デフォルトでBLOBのバイト数またはCLOBとNCLOBの文字数がプリフェッチされるよう指定できます。

文レベルで次のTimesTenStatementメソッドを使用すると、接続のプリフェッチ・サイズの操作とデフォルト値の上書きが可能になります。

- setLobPrefetchSize(int): 文の新しいLOBプリフェッチ値を指定します。

- int getLobPrefetchSize(): 文に適用されている現在のLOBプリフェッチ値を戻します(該当する文自体に設定した値または接続のデフォルト値)。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

パススルーLOB

パススルーLOB(TimesTenを介してアクセスするOracle Database内のLOB)は、TimesTenのLOBとして公開され、TimesTenのLOBがサポートされているのとほぼ同様にTimesTenでサポートされていますが、次のことに注意する必要があります。

- 「TimesTenのLOBインタフェース・メソッド」のとおり、TimesTenBlob、TimesTenClobおよびTimesTenNClobインタフェースでは、そのLOBがパススルーLOBであるかを示す次のメソッドを規定しています。
boolean isPassthrough()

- TimesTenのLOBのサイズ制限は、パススルーによるOracle DatabaseのLOBの保存には適用されません。

- TimesTenのローカルのLOBと同様に、パススルーLOBオブジェクトはトランザクションが終了すると無効になります。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

データベースに対する変更のコミットまたはロールバック

この項では、自動コミットおよび手動コミット、またはロールバックについて説明します(JDBC Connectionオブジェクトをmyconn、Statementオブジェクトをmystmtと仮定しています)。

注意:
接続上のすべてのオープン・カーソルは、TimesTenでのトランザクションのコミットまたはロールバック時にクローズされます。

トランザクションの詳細は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のトランザクションの概要に関する説明を参照してください。

自動コミットの設定

TimesTen接続は、デフォルトで自動コミットが有効になっていますが、パフォーマンス上の理由で無効にすることをお薦めします。ConnectionメソッドsetAutoCommit()を使用して、自動コミットの有効/無効を切り替えることができます。

次のように自動コミットを無効にします。

myconn.setAutoCommit(false);
// Report any SQLWarnings on the connection.
// See "Reporting errors and warnings".

手動コミットまたは変更のロールバック

自動コミットが無効化された場合、Connectionメソッドcommit()を使用して手動でトランザクションをコミットするか、またはrollback()メソッドを使用して変更をロールバックする必要があります。次の例を想定してください。

myconn.commit();

または

myconn.rollback();

COMMIT文およびROLLBACK SQL文の使用

SQLのCOMMIT文およびROLLBACK文は、他のSQL文と同様に準備して実行できます。COMMIT文およびROLLBACK文の使用は、Connectionメソッドcommit()およびrollback()の使用と同じ結果になります。次に例を示します。

mystmt.execute("COMMIT");

複数スレッドの管理

注意:
一部のUNIXプラットフォームでは、THREADS_FLAGを『Oracle TimesTen In-Memory Databaseインストレーション・ガイド』のTHREADS_FLAG変数の設定に関する説明に従って設定する必要があります。

level4デモでは、複数スレッドの使用について説明します。「TimesTen Javaのデモ」を参照してください。

アプリケーションにデータベースに対する直接接続がある場合、TimesTenファンクションはアプリケーションとスタック空間を共有します。マルチスレッド環境では、デバッグが困難な予測不能な状態でプログラムがクラッシュする可能性があるため、各スレッドに割り当てたスタックが超過しないようにすることが重要です。TimesTenのコールが消費するスタック空間は、使用するSQLの機能によっても異なります。大部分のアプリケーションでは、32ビット・システムでは最低16KB、64ビット・システムでは34KBから72KBの間のスタック空間を設定する必要があります。

各スレッドに割り当てられるスタック空間の量は、スレッドの作成時にオペレーティング・システムが指定します。Windowsでは、TimesTenデバッグ・ドライバを使用し、Visual C++デバッグCライブラリとアプリケーションをリンクすると、スレッドが割当て量よりもそのスタックを拡張しようとするときに識別可能な例外を発生させる、スタック・プローブが有効になります。

注意:
マルチスレッド・アプリケーションでは、同じデータベースへの様々な接続ハンドルにリクエストを発行するスレッドで、それ自身とのロック競合が発生する可能性があります。TimesTenは、この状況でロック・タイムアウトおよびデッドロック・エラーを返します。

Javaのエスケープ構文およびSQLファンクション

JDBCでSQLを使用する際は、Javaエスケープ構文に特に注意します。UNISTRなどのSQLファンクションは、バックスラッシュ文字(\)を使用します。バックスラッシュ文字は、エスケープする必要があります。たとえば、Javaアプリケーションで次のSQL構文を使用すると、意図した結果にならない場合があります。

INSERT INTO table1 SELECT UNISTR('\00E4') FROM dual;

バックスラッシュ文字を次のようにエスケープします。

INSERT INTO table1 SELECT UNISTR('\\00E4') FROM dual;

その他のTimesTenデータ管理機能の使用

前述の項では、TimesTenデータを管理する際の主な機能について説明しました。この項では、次の追加の機能について説明します。

- プロシージャおよびファンクションを実行するためのCALLの使用

- SQL文の実行に対するタイムアウトまたはしきい値の設定

- TimesTen Cacheで使用する機能

- レプリケーションで使用する機能

プロシージャおよびファンクションを実行するためのコールの使用

TimesTenでは、(スタンドアロンの場合とパッケージの一部である場合がある)PL/SQLプロシージャ(procname)またはPL/SQLファンクション(funcname)をコールする、またはTimesTen組込みプロシージャ(procname)をコールする、そのすべてのプログラミング・インタフェースの次の各構文書式をサポートしています。

CALL procname[(argumentlist)]

CALL funcname[(argumentlist)] INTO :returnparam

CALL funcname[(argumentlist)] INTO ?

TimesTenのJDBCでは、次の構文の書式もサポートしています。

{ CALL procname[(argumentlist)] }

{ ? = [CALL] funcname[(argumentlist)] }

{ :returnparam = [CALL] funcname[(argumentlist)] }

プロシージャおよびファンクションは、(結果セットをいつ返すかなどの)準備ステップがある場合はそれを先にして、CallableStatementインタフェースを介して実行します。

次の例では、TimesTen組込みプロシージャのttCkptをコールしています(より完全なJDBCの構文例については、例2-13も参照してください)。

CallableStatement.execute("call ttCkpt")

次の例では、TimesTen組込みプロシージャのttDataStoreStatusをコールしています。このプロシージャでは結果セットが生成されるため、準備コールが使用されています。(より完全なJDBCの構文例については、例2-14も参照してください)。

CallableStatement cStmt = null;
cStmt = conn.prepareCall("call ttDataStoreStatus");
cStmt.execute();

次の例では、2つのパラメータを使用し、PL/SQLプロシージャmyprocをコールしています。

cStmt.execute("{ call myproc(:param1, :param2) }");

cStmt.execute("{ call myproc(?, ?) }");

次にPL/SQLファンクションmyfuncをコールするいくつかの方法を示します。

cStmt.execute("CALL myfunc() INTO :retparam");

cStmt.execute("CALL myfunc() INTO ?");

cStmt.execute("{ :retparam = myfunc() }");

cStmt.execute("{ ? = myfunc() }");

CALL構文の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス』のCALLに関する説明を参照してください。

注意:
ユーザー独自のプロシージャは、同じ名前を持ったTimesTen組込みプロシージャより優先されますが、このような命名の競合は回避することが最適です。

例2-13 ttCkptコールの実行

この例では、ttCkptプロシージャをコールしてファジー・チェックポイントを開始します。

Connection conn = null;
CallableStatement cStmt = null;
.......
cStmt = conn.prepareCall("{ Call ttCkpt }");
cStmt.execute();
conn.commit();           // commit the transaction

ttCkpt組込みプロシージャには、ADMIN権限が必要なことに注意してください。その他の情報については、『Oracle TimesTen In-Memory Databaseリファレンス』のttCkptに関する項を参照してください。

例2-14 ttDataStoreStatusコールの実行

この例では、ttDataStoreStatusプロシージャをコールして、返される結果セットを出力します。

結果セットを返す組込みプロシージャについては、ResultSetインタフェースのgetXXX()メソッドを使用して、次のようにデータを取得できます。

「TimesTen結果セットの使用: ヒントおよび制限」に示した例とは異なり、この例では、ResultSetオブジェクトでgetString()コールを使用して、バイナリであるContextフィールドを取得します。これは、出力は処理で使用されるのではなく、表示されるためです。Context値を表示しない場合は、getBytes()メソッドをかわりに使用すると、より高いパフォーマンスが得られます。

ResultSet rs;

CallableStatement cStmt = conn.prepareCall("{ Call ttDataStoreStatus }");

if (cStmt.execute() == true) {
rs = cStmt.getResultSet();
System.out.println("Fetching result set...");
while (rs.next()) {
System.out.println("\n Database: " + rs.getString(1));
System.out.println(" PID: " + rs.getInt(2));
System.out.println(" Context: " + rs.getString(3));
System.out.println(" ConType: " + rs.getString(4));
System.out.println(" memoryID: " + rs.getString(5));
}
rs.close();
}
cStmt.close();

SQL文の実行に対するタイムアウトまたはしきい値の設定

TimesTenには、SQL文の実行時間を制限する2通りの方法があり、execute()、executeBatch()、executeQuery()、executeUpdate()またはnext()のコールで使用できます。

- SQL文のタイムアウト期間の設定

- SQL文のしきい値期間の設定

前者では、タイムアウト期間になると文の実行が停止しエラーがスローされる、タイムアウトを設定します。後者では、しきい値に達すると、SNMPトラップがスローされますが実行は継続される、しきい値を設定します。

SQL文のタイムアウト期間の設定

TimesTenでは、SqlQueryTimeout一般接続属性を設定して、接続(つまり、接続の任意の文)に対してタイムアウト期間(秒)を指定できます。(『Oracle TimesTen In-Memory Databaseリファレンス』のSqlQueryTimeoutに関する説明も参照してください。)値0はタイムアウトが発生しないことを示します。名前に反して、このタイムアウト値は問合せだけでなく、実行可能な任意のSQL文に適用されます。

特定の文について、StatementメソッドsetQueryTimeout()をコールすることで、SqlQueryTimeout設定を上書きすることができます。

問合せのタイムアウト制限は、SQL文がアクティブに実行されている場合のみ有効です。処理のコミット中またはロールバック中にタイムアウトは発生しません。多数の行を更新、挿入、削除するトランザクションでは、コミットまたはロールバックの行程が完了するまでに時間がかかる場合があります。その間、タイムアウト値は無視されます。

注意:
ロック・タイムアウト値およびSQL問合せタイムアウト値の両方が指定されている場合は、まず、2つの値の小さい方の値によってタイムアウトが発生します。ロック・タイムアウトについては、『Oracle TimesTen In-Memory Databaseリファレンス』のttLockWait(組込みプロシージャ)またはLockWait(一般接続属性)に関する説明、またはOracle TimesTen In-Memory Databaseトラブルシューティング・ガイドのデッドロックとタイムアウトの確認に関する説明を参照してください。

SQL文のしきい値期間の設定

SQL文の実行時間が、指定した期間(秒)を超えたときに、サポート・ログに警告を書き込み、SNMPトラップをスローするように、TimesTenを構成できます。実行は継続され、しきい値の影響は受けません。

SNMPトラップの名前は、ttQueryThresholdWarnTrapです。SNMPトラップの構成に関する情報は、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』を参照してください。

名前に反して、このしきい値は問合せだけでなく、SQL文を実行する任意のJDBCコールに適用されます。

デフォルトでは、アプリケーションはしきい値をQueryThreshold一般接続属性設定から取得します。データベースの接続URLにQueryThreshold属性を含めることでJDBC Connectionオブジェクトのしきい値を上書きすることができます。たとえば、QueryThresholdの値をmyDSNデータベース用に5秒に設定するには、次のようにします。

jdbc:timesten:direct:dsn=myDSN;QueryThreshold=5

TimesTenStatementオブジェクトのsetQueryTimeThreshold()メソッドを使用して、しきい値を設定することもできます。これは、接続属性設定およびConnection オブジェクト設定を上書きします。

TimesTenStatementオブジェクトのgetQueryTimeThreshold()メソッドを使用して現行のしきい値を取得できます。

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

TimesTen Cacheで使用する機能

この項では、TimesTen Application-Tier Database Cache (TimesTen Cache)の使用に関係する機能について説明します。

- ttOptSetFlag組込みプロシージャでの一時パススルー・レベルの設定

- キャッシュ・グループの管理

注意:
OraclePassword属性は、Oracle Databaseパスワードにマップされます。TimesTenDataSourceメソッドsetOraclePassword()を使用してOracle Databaseのパスワードを設定できます。例は、「データベースへの接続」を参照してください。

ttOptSetFlag組込みプロシージャでの一時パススルー・レベルの設定

TimesTenでは、パススルー・レベルを一時的に設定するPassThroughフラグを含め、様々なフラグの設定にttOptSetFlag組込みプロシージャを用意しています。ttOptSetFlagを使用すると、次のサンプル文のようにJDBCアプリケーションでPassThroughを設定できます(この場合、パススルー・レベルは1に設定されます)。この設定は、トランザクションの最後までの準備されているすべての文に影響します。

pstmt = conn.prepareStatement("call ttoptsetflag('PassThrough', 1)");

次の例には、これらの手順を実行するサンプル・コードがあります。

1. パススルー・レベル用に、バインド・パラメータを使用するttOptSetFlagをコールする準備済文(PreparedStatementインスタンスthePassThroughStatement)を作成します。

2. 指定したパススルー設定を取るメソッドsetPassthrough()を定義し、これを準備済文にバインドし、準備済文を実行して、パススルー・レベルを設定するttOptSetFlagをコールします。

thePassThroughStatement =
theConnection.prepareStatement("call ttoptsetflag('PassThrough', ?)");
...
private void setPassthrough(int level) throws SQLException{
thePassThroughStatement.setInt(1, level);
thePassThroughStatement.execute();
}

この組込みプロシージャの詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のttOptSetFlagに関する説明を参照してください。

この一般接続属性の詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のパススルーに関する説明を参照してください。パススルー設定の詳細は、『Oracle TimesTen Application-Tier Database Cacheユーザーズ・ガイド』のパススルー・レベルの設定に関する説明を参照してください。

キャッシュ・グループの管理

TimesTenで、FLUSH CACHE GROUP、LOAD CACHE GROUP、REFRESH CACHE GROUPまたはUNLOAD CACHE GROUP文を実行すると、StatementメソッドgetUpdateCount()によって、フラッシュ、ロード、リフレッシュ、アンロードされたキャッシュ・インスタンスの数が返されます。

関連する情報について、『Oracle TimesTen Application-Tier Database Cacheユーザーズ・ガイド』の操作で影響を受けたキャッシュ・インスタンスの数の判別に関する説明を参照してください。

レプリケーションで使用する機能

レプリケーションを使用するアプリケーションの場合、パラレル・レプリケーションを使用することでパフォーマンスを向上させることができます。パラレル・レプリケーションでは、並行して動作する複数のスレッドを使用して、レプリケーション・スキーム内のノードにトランザクションの変更をレプリケートおよび適用します。TimesTenでは、次のタイプのパラレル・レプリケーションをサポートしています。

- 自動パラレル・レプリケーション(ReplicationApplyOrdering=0): トランザクションの依存性と、コミット順に適用されたすべての変更を自動的に強制する、複数のスレッドにおけるパラレル・レプリケーション。これはデフォルトです。

- コミット依存性を無効にした自動パラレル・レプリケーション(ReplicationApplyOrdering=2): トランザクションの依存性を自動的に強制するが、サブスクライバ・データベース上でマスター・データベース上と同じ順序でコミットされるトランザクションは強制しない、複数スレッドでのパラレル・レプリケーション。このモードでは、オプションでレプリケーション・トラックを指定できます。

- ユーザー定義のパラレル・レプリケーション()ReplicationApplyOrdering=1: クラシック・レプリケーション・スキームを使用し、トランザクションの依存性の予測性が高く、レシーバでのコミット順序が元のデータベース上のコミット順序と同じである必要がないアプリケーションの場合。トランザクションの追跡数を指定し、各追跡に特定のトランザクションを適用できます。すべての追跡の読取り、送信および適用はパラレルに行われます。

詳細および使用方法のシナリオについては、『Oracle TimesTen In-Memory Database開発者および管理者ガイド』のパラレル・レプリケーションの構成に関する説明を参照してください。

パラレル・レプリケーションを使用し、レプリケーション・トラックを指定するJDBCアプリケーションの場合は、後述のTimesTenConnectionメソッドを通じて、接続でトラック番号を指定できます。(または、一般接続属性のReplicationTrackまたはALTER SESSIONパラメータREPLICATION_TRACKを使用します)。

- void setReplicationTrack(int track)

TimesTenConnectionにも、対応するgetterメソッドがあります。

- int getReplicationTrack()

詳細は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』を参照してください。

注意:
ユーザー定義のパラレル・レプリケーションは通常、お薦めできません。レプリケーション・ノード間のデータの相違を回避するために注意する必要があるためです。

アクセス制御のためのTimesTen機能の検討

TimesTenには、データベース・オブジェクト(表、ビュー、マテリアライズド・ビュー、順序およびシノニムなど)をオブジェクト・レベルで分解することによる、データベース・アクセス制御の機能があります。TimesTenアクセス制御の概要については、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のアクセス制御の管理に関する項を参照してください。

この項では、SQL操作、データベース接続およびJMS/XLAに関連するアクセス制御について説明します。

このマニュアルで説明されている、または例で使用されている問合せ、SQL DMLまたはDDL文では、ユーザーは、その文の実行のために適切な権限を持っていることを前提としています。たとえば、表に対するSELECT文では、その表の所有権、その表に関して付与されているSELECT権限またはSELECT ANY TABLEシステム権限が必要です。同様に、DML文にはその表の所有権、その表に関して付与されている適切なDML権限(UPDATEなど)または適切なANY TABLE権限(UPDATE ANY TABLEなど)が必要です。

DDL文の場合、CREATE TABLEにはユーザー・スキーマのCREATE TABLE権限またはその他のスキーマのCREATE ANY TABLE権限が必要です。ALTER TABLEは、所有権またはALTER ANY TABLEシステム権限を必要とします。DROP TABLEは、所有権またはDROP ANY TABLEシステム権限を必要とします。オブジェクト・レベルのALTER権限またはDROP権限はありません。

アクセス制御権限のリストおよび与えられたSQL文に必要な権限については、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のSQL文に関する項を参照してください。

権限は、SQLのGRANT文で付与され、REVOKE文で取り消されます。一部の権限は、すべてのユーザーがメンバーになっているPUBLICロールによって自動的にすべてのユーザーに付与されます。このロールに関する情報は、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のPUBLICロールに関する項を参照してください。

また、アクセス制御は、このマニュアルで説明している次の内容に関係します。

- データベースへの接続: 「接続のアクセス制御」を参照してください。

- 接続属性の設定: 「データベースの接続URLの作成および接続属性の指定」を参照してください。

- JMS/XLAの構成および管理。「アクセス制御がXLAに与える影響」を参照してください。

注意:

- アクセス制御を無効にすることはできません。

- アクセス制御権限は、SQLの準備時およびそのSQL文のデータベースでの実行時の両方で確認され、大部分のパフォーマンス・コストは準備時に発生します。

エラー処理

この項では、TimesTen Javaアプリケーションで発生するエラーの検出、識別および処理について説明します。

TimesTenにより返されるエラーのリストおよびエラーが発生した場合の対処方法については、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』の警告およびエラーに関する章を参照してください。

この項の内容は次のとおりです。

- 致命的エラー、致命的でないエラーおよび警告

- エラーおよび警告のレポート

- 特定のエラーの検出および対応

- 失敗したトランザクションのロールバック

致命的エラー、致命的でないエラーおよび警告

操作が完全には成功しない場合、TimesTenは、致命的なエラー、致命的ではないエラーまたは警告を返すことができます。

致命的エラーの処理

致命的なエラーが発生すると、リカバリするまでデータベースにアクセスできなくなります。致命的なエラーが発生すると、すべてのデータベースの接続を切断する必要があります。それ以後の処理は完了されません。致命的エラーは、TimesTenのエラー・コード846および994で示されます。これらのエラーの処理は、標準的なエラーの処理とは異なります。特に、コードで現行のトランザクションをロールバックし、サーバーでのメモリー不足状態を避けるためにデータベースからの接続を切断する必要があります。古いTimesTenインスタンスの共有メモリーは、エラー発生時にアクティブだったすべての接続が切断されるまで解放されません。古いTimesTenインスタンスに引き続き接続されている非アクティブなアプリケーションは、手動で終了する必要があることがあります。

致命的エラーが発生した場合、TimesTenは、次の完全なクリーンアップおよびリカバリ・プロシージャを実行します。

- データベースに対するすべての接続を無効し、新しいメモリー・セグメントを割り当て、アプリケーションを切断します。

- その後の最初の初期接続時に、チェックポイント・ファイルおよびトランザクション・ログ・ファイルからデータベースをリカバリします。

- リカバリされたデータベースには、永続コミットされたすべてのトランザクションの状態が反映され、非永続的にコミットされた一部のトランザクションも反映されます。

- コミットされていないトランザクションまたはロールバックされたトランザクションは反映されません。

致命的ではないエラーの処理

致命的ではないエラーには、一意制約に違反しているINSERT文などの単純なエラーが含まれます。また、一部のアプリケーション障害およびプロセス障害も、致命的ではないエラーに含まれます。

TimesTenは、通常のエラー処理プロセスを介して致命的ではないエラーを返します。アプリケーションは、エラーがないか確認し、これらを適切に処理する必要があります。

致命的ではないエラーによってデータベースに影響が出た場合、エラーが返されることがあり、アプリケーションで適切に対処する必要があります。

アプリケーションでは、その処理を変更するか、または障害が発生した1つ以上のトランザクションをロールバックすることによって、致命的ではないエラーに対処できます。詳細は、「失敗したトランザクションのロールバック」を参照してください。

後述の「エラーおよび警告のレポート」も参照してください。

注意:
ResultSet、Statement、PreparedStatement、CallableStatementまたはConnection操作でデータベースにエラーが発生する場合は、そのオブジェクトに対してclose()メソッドをコールすることをお薦めします。

警告について

TimesTenは予期しない問題が発生した場合に警告を返します。たとえば、次の状況が発生した場合、TimesTenは警告を発行します。

- チェックポイントの障害

- 非推奨のTimesTen機能の使用

- 一部のデータの切捨て

- 接続時のリカバリ処理の実行

- レプリケーションがRETURN RECEIPTの場合のタイムアウト

アプリケーションの問題を示すことができるように、警告をチェックするコードを常に含める必要があります。

すぐ下の「エラーおよび警告のレポート」も参照してください。

異常終了

プロセスの障害などの場合はエラーが返されないため、失敗したプロセスのトランザクションが自動的にロールバックされます。

エラーおよび警告のレポート

コールのたびに返される可能性があるすべてのエラーと警告を確認してレポートする必要があります。これによって、開発およびデバッグの時間および労力が大幅に削減されます。データベースのアクセス時にエラーが1つ以上ある場合は、SQLExceptionオブジェクトが発生し、警告メッセージが1つ以上ある場合は、SQLWarningオブジェクトが発生します。1回のコールで複数のエラーまたは警告(あるいはその両方)が返されることがあるため、アプリケーションでは、返されたSQLExceptionオブジェクトまたはSQLWarningオブジェクトにすべてのエラーまたは警告をレポートする必要があります。

SQLExceptionオブジェクトまたはSQLWarningオブジェクトのリンク連鎖では、複数のエラーまたは警告が返されます。例2-15および例2-16に、返されたSQLExceptionオブジェクトとSQLWarningオブジェクトのリストで繰り返し実行し、それぞれにすべてのエラーと警告をレポートする方法を示します。

例2-15 例外の表示

次のメソッドは、リンクされたSQLExceptionオブジェクトのすべての例外の内容を表示します。

static int reportSQLExceptions(SQLException ex)
{
int errCount = 0;
if (ex != null) {
errStream.println("\n--- SQLException caught ---");
ex.printStackTrace();

while (ex != null) {
errStream.println("SQL State: " + ex.getSQLState());
errStream.println("Message: " + ex.getMessage());
errStream.println("Error Code: " + ex.getErrorCode());
errCount ++;
ex = ex.getNextException();
errStream.println();
}
}

return errCount;
}

例2-16 警告の表示

このメソッドは、リンクされたSQLWarningオブジェクトのすべての例外の内容を表示します。

static int reportSQLWarnings(SQLWarning wn)
{
int warnCount = 0;

while (wn != null) {
errStream.println("\n--- SQL Warning ---");
errStream.println("SQL State: " + wn.getSQLState());
errStream.println("Message: " + wn.getMessage());
errStream.println("Error Code: " + wn.getErrorCode());

// is this a SQLWarning object or a DataTruncation object?
if (wn instanceof DataTruncation) {
DataTruncation trn = (DataTruncation) wn;
errStream.println("Truncation error in column: " +
trn.getIndex());
}
warnCount++;
wn = wn.getNextWarning();
errStream.println();
}
return warnCount;
}

特定のエラーの検出および対応

一部の状況では、特定のSQLの状態またはTimesTenエラー・コードに応答することが望ましい場合があります。SQLExceptionメソッドgetSQLState()を使用すると、例2-17のように、SQLの状態を戻すことができ、getErrorCode()メソッドを使用すると、TimesTenエラー・コードを戻すことができます。

エラーの情報は、『Oracle TimesTen In-Memory Database JDBC Extensions Java API Reference』のTimesTenVendorCodeに関する項も参照してください。

例2-17 エラーの検出

TimesTenのデモでは、デモ・スキーマをロードしてから実行する必要があります。ODBCエラーS0002およびTimesTenエラー907が検出されると、次のcatch文により、appuserがロードまたは更新されていないというアラートがユーザーに発行されます。

catch (SQLException ex) {
if (ex.getSQLState().equalsIgnoreCase("S0002")) {
errStream.println("\nError: The table appuser.customer " +
"does not exist.\n\t Please reinitialize the database.");
} else if (ex.getErrorCode() == 907) {
errStream.println("\nError: Attempting to insert a row " +
"with a duplicate primary key.\n\tPlease reinitialize the database.");
}

TimesTenVendorCodeインタフェースを使用すると、番号ではなく名前によって、エラーを検出できます。

次の例を検討してください。

ex.getErrorCode() == com.timesten.jdbc.TimesTenVendorCode.TT_ERR_KEYEXISTS

次が同等です。

ex.getErrorCode() == 907

失敗したトランザクションのロールバック

デッドロックからのリカバリやロック・タイムアウトなど、いくつかの状況では、次の例のようにConnectionのメソッドrollback()を使用して、トランザクションを明示的にロールバックする必要があります。

例2-18 トランザクションのロールバック

try {
if (conn != null && !conn.isClosed()) {
// Rollback any transactions in case of errors
if (retcode != 0) {
try {
System.out.println("\nEncountered error. Rolling back transaction");
conn.rollback();
} catch (SQLException ex) {
reportSQLExceptions(ex);
}
}
}

System.out.println("\nClosing the connection\n");
conn.close();
} catch (SQLException ex) {

reportSQLExceptions(ex);
}

SYS.MONITOR表のXACT_ROLLBACKS列は、ロールバックされたトランザクションの数を示します。詳細は、『Oracle TimesTen In-Memory Databaseシステム表およびビュー・リファレンス』のSYS.MONITORに関する説明を参照してください。

トランザクションのロールバックによってリソースが消費され、結果的にトランザクション全体が無駄になってしまいます。不要なロールバックを回避するには、競合が発生しないようにアプリケーションを設計し、送信前にアプリケーションまたは入力データをチェックしてエラーを検出する必要があります。

注意:
アクティブなトランザクションの途中でアプリケーションが中断、クラッシュまたは切断した場合、TimesTenはトランザクションを自動的にロールバックします。

自動クライアント・フェイルオーバーのJDBCサポート

自動クライアント・フェイルオーバーは、レプリケーションが構成されたTimesTenのアクティブなスタンバイ・ペアにおける高可用性のシナリオで使用します。アクティブ・ノードに障害があると、新しいアクティブ(元のスタンバイ)・ノードへのフェイルオーバー(転送)が発生し、アプリケーションは新しいアクティブ・ノードに自動的に再接続されます。TimesTenは自動クライアント・フェイルオーバーが発生したときに、アプリケーションに警告を渡す機能を提供しているため、アプリケーションは適切な処理を行うことができます。

この項では、自動クライアント・フェイルオーバーに関連するTimesTen JDBC拡張について説明します。次の内容について説明します。

- 自動クライアント・フェイルオーバーのJDBCサポートの特徴および機能

- 自動クライアント・フェイルオーバーの構成

- 自動クライアント・フェイルオーバーの同期検出

- 自動クライアント・フェイルオーバーの非同期検出

注意:
自動クライアント・フェイルオーバーは、クライアント/サーバー接続にのみ適用されます。ここで説明する機能は、直接接続には使用できません。

Oracle Clusterwareを使用する場合、自動クライアント・フェイルオーバーはOracle Clusterwareに対する補完機能ですが、この2つの機能は互いに依存しません。

自動クライアント・フェイルオーバーの一般情報は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』の自動クライアント・フェイルオーバーの使用に関する説明を、開発者向けの関連情報は、『Oracle TimesTen In-Memory Database C開発者ガイド』のアプリケーションでの自動クライアント・フェイルオーバーの使用に関する説明を参照してください。

Oracle Clusterwareの詳細は、『Oracle TimesTen In-Memory Database開発者および管理者ガイド』のOracle Clusterwareを使用してのアクティブ・スタンバイ・ペアの管理に関する項を参照してください。

自動クライアント・フェイルオーバーのJDBCサポートの特徴および機能

この項では、クライアント・フェイルオーバーに関係する一般的なTimesTen JDBC機能(特にプールされた接続に関係する機能)について説明します。

ここで説明するTimesTenのJDBCクラス、インタフェース、メソッドの詳細は、Oracle TimesTen In-Memory Database JDBC拡張Java APIリファレンスを参照してください。

一般的なクライアント・フェイルオーバー機能

自動クライアント・フェイルオーバーに対するTimesTen JDBCサポートには、フェイルオーバーを検出するために次の2つのメカニズムがあります。

- SQL例外での同期検出: 自動クライアント・フェイルオーバー後、障害が発生した接続に作成された文、準備済文、コール可能な文および結果セットなどのJDBCオブジェクトは使用できなくなります。そのようなオブジェクトにアプリケーションがアクセスを試みた場合、Java SQL例外がスローされます。その例外のSQL状態およびエラーコードを確認することで、例外が、フェイルオーバーの状況の結果であるかどうかを判断できます。

- イベント・リスナーでの非同期検出: アプリケーションでは、フェイルオーバーのプロセスで発生する各イベントの通知対象となるユーザー定義のクライアント・フェイルオーバー・イベント・リスナーを登録できます。

TimesTen JDBCは、パッケージcom.timesten.jdbcで自動クライアント・フェイルオーバーをサポートするために次の機能を提供します。

- ClientFailoverEventクラス
このクラスは、クライアント・フェイルオーバー中に発生したイベント(開始、終了、中止または再試行)を表現するために使用されます。

- ClientFailoverEventListenerインタフェース
クライアントのフェイルオーバー・イベントが関係するアプリケーションでは、クライアントのフェイルオーバー・イベントをリスニングするメカニズムである、このインタフェースを実装するクラスを含める必要があります。アプリケーションの実行時に、TimesTen接続を介してClientFailoverEventListenerインスタンスを登録する必要があります(直下を参照)。

リスナーを使用すると、障害の検出時に、接続プール文キャッシュのリフレッシュなどを行って積極的に対応できます。

- TimesTenConnectionインタフェースの新しいメソッド
このインタフェースはメソッドaddConnectionEventListener()およびremoveConnectionEventListener()を指定し、それぞれクライアント・フェイルオーバー・イベント・リスナーの登録または削除を行います。

- TimesTenVendorCodeインタフェースの新しい定数TT_ERR_FAILOVERINVALIDATION
これは、イベントがフェイルオーバー・イベントであると確認できます。

プールされた接続のクライアント・フェイルオーバー機能

TimesTenでは、プールされた接続(javax.sql.PooledConnection)または接続プール・データソース(javax.sql.ConnectionPoolDataSource)を使用するアプリケーションで、前述の同期メカニズムを使用し、障害が発生した接続で失効したオブジェクトを処理することをお薦めします。プールされた接続はJava EEアプリケーション・サーバーで管理するため、プールされた接続でのイベントをアプリケーションでリスニングすることはできません。また、アプリケーション・サーバーでは、TimesTenの拡張であるClientFailoverEventListenerのインスタンスの実装および登録を行いません。

自動クライアント・フェイルオーバーの構成

詳細は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』の自動クライアント・フェイルオーバーの構成に関する説明を参照してください。

注意:
TTC_Server2、TTC_Server_DSN2またはTCP_Port2のいずれかを設定することは、暗黙的に次のことを意味します。

- ユーザーは、自動クライアント・フェイルオーバーを使用するつもりである。

- ユーザーは、フェイルオーバー・メカニズムをサポートするためにアプリケーションに新しいスレッドが作成されることを理解している。

- アプリケーションをスレッド・ライブラリにリンクしました(UNIXシステムでのpthread)。

自動クライアント・フェイルオーバーの同期検出

フェイルオーバー時に、障害が発生した接続に作成されたオブジェクトをアプリケーションで使用しようとすると、JDBCはSQL例外をスローします。ベンダー固有の例外コードは、TimesTenVendorCode.TT_ERR_FAILOVERINVALIDATIONに設定されます。

このメカニズムによるフェイルオーバーの検出は、同期検出として示されます。次の例でこれを説明します。

例2-19 自動クライアント・フェイルオーバーの同期検出

try {
// ...
// Execute a query on a previously prepared statement.
ResultSet theResultSet = theStatement.executeQuery("select * from dual");
// ...

} catch (SQLException sqlex) {
sqlex.printStackTrace();
if (sqlex.getErrorCode() == TimesTenVendorCode.TT_ERR_FAILOVERINVALIDATION) {
// Automatic client failover has taken place; discontinue use of this object.
}
}

自動クライアント・フェイルオーバーの非同期検出

非同期のフェイルオーバーの検出には、アプリケーションでクライアント・フェイルオーバー・イベント・リスナーを実装し、そのインスタンスをTimesTen接続に登録する必要があります。この項では、その手順を説明します。

1. クライアント・フェイルオーバー・イベント・リスナーを実装します。

2. クライアント・フェイルオーバー・リスナー・インスタンスを登録します。

3. クライアント・フェイルオーバー・リスナー・インスタンスを削除します。

クライアント・フェイルオーバー・イベント・リスナーの実装

TimesTen JDBCは、(次のメソッドで強調されている)イベントのリスニングに使用するcom.timesten.jdbc.ClientFailoverEventListenerインタフェースを提供します。

- void notify(ClientFailoverEvent event)

非同期フェイルオーバー検出を使用するには、このインタフェースを実装するクラスを作成した後、TimesTen接続の実行時に、クラスのインスタンスを登録する必要があります(概要が説明されています)。

フェイルオーバー・イベントが発生すると、TimesTenは、登録したリスナー・インスタンスのnotify()メソッドをコールして、イベントに関する情報を確認することができるClientFailoverEventインスタンスを提供します。

次の例は、ClientFailoverEventListener実装の基本的な形式を示しています。

例2-20 自動クライアント・フェイルオーバーの非同期検出

private class MyCFListener implements ClientFailoverEventListener {
/* Applications can build state system to track states during failover.
You may want to add methods that talks about readiness of this Connection
for processing.
*/
public void notify(ClientFailoverEvent event) {

/* Process connection failover type */
switch(event.getTheFailoverType()) {
case TT_FO_CONNECTION:
/* Process session fail over */
System.out.println("This should be a connection failover type " +
event.getTheFailoverType());
break;

default:
break;
}
/* Process connection failover events */
switch(event.getTheFailoverEvent()) {
case BEGIN:
System.out.println("This should be a BEGIN event " +
event.getTheFailoverEvent());
/* Applications cannot use Statement, PreparedStatement, ResultSet,
etc. created on the failed Connection any longer.
*/
break;

case END:
System.out.println("This should be an END event " +
event.getTheFailoverEvent());

/* Applications may want to re-create Statement and PreparedStatement
objects at this point as needed.
*/
break;

case ABORT:
System.out.println("This should be an ABORT event " +
event.getTheFailoverEvent());
break;

case ERROR:
System.out.println("This should be an ERROR event " +
event.getTheFailoverEvent());
break;

default:
break;
}
}
}

event.getTheFailoverType()コールは、ネストされた列挙型のクラスClientFailoverEvent.FailoverTypeのインスタンスを返します。TimesTenでは唯一サポートされる値は、接続のフェイルオーバーを示すTT_FO_CONNECTIONです。

event.getTheFailoverEvent()コールは、ネストされたクラスClientFailoverEvent.FailoverEventのインスタンスを返します。これは列挙型で、その値は次のいずれかにあります。

- クライアント・フェイルオーバーが開始した場合は、BEGIN

- クライアント・フェイルオーバーが正常に完了した場合は、END

- クライアントのフェイルオーバーは失敗したが、再試行される場合は、ERROR

- クライアント・フェイルオーバーが中断した場合は、ABORT

クライアント・フェイルオーバー・リスナー・インスタンスの登録

実行時、フェイル・オーバー・イベント・リスナー・クラスのインスタンスを、TimesTen接続オブジェクトに登録する必要があります。そうすることで、フェイルオーバー・イベントに必要な、そのリスナー・クラスのnotify()メソッドをコールすることができるようになります。

これを実行するため、TimesTenConnectionには、次のメソッドがあります。

- void addConnectionEventListener (ClientFailoverEventListener listener)

リスナー・クラスのインスタンスを作成した後、このメソッドを使用して登録します。次の例では、接続を確立した後にリスナーを登録します。theDsnがTimesTenクライアント/サーバー・データベースのJDBC URLで、theCFListenerがフェイルオーバー・イベント・リスナー・クラスのインスタンスだと仮定します。

例2-21 クライアント・フェイルオーバー・リスナーの登録

try {
/* Assume this is a client/server conn; register for conn failover. */
Class.forName("com.timesten.jdbc.TimesTenClientDriver");
String url = "jdbc:timesten:client:" + theDsn;
theConnection = (TimesTenConnection)DriverManager.getConnection(url);
theConnection.addConnectionEventListener(theCFListener);
/* Additional logic goes here; connection failover listener is
called if there is a fail over.
*/
}
catch (ClassNotFoundException cnfex) {
cnfex.printStackTrace();
}
catch (SQLException sqlex) {
sqlex.printStackTrace();
}

クライアント・フェイルオーバー・リスナー・インスタンスの削除

TimesTenConnectionインタフェースは次のメソッド定義して、フェイルオーバー・イベント・リスナーを登録解除します。

- void removeConnectionEventListener (ClientFailoverEventListener listener)

リスナー・インスタンスを登録解除する場合は、このメソッドを使用します。

3 イベント管理のためのJMS/XLAの使用

TimesTen JMS/XLA APIを使用すると、ローカル・データベース内の特定の表への変更についてTimesTenを監視し、これらの変更の通知をリアルタイムで受信できます。JMS/XLAの主な目的は、トリガーの代替手段として、高性能かつ非同期の機能を提供することです。

JMS/XLAはJava Message Service(JMS)インタフェースを実装しているため、JavaアプリケーションでTimesTenトランザクション・ログAPI(XLA)機能を使用できます。JMSの情報およびリソースは、次の場所から利用可能です。

http://www.oracle.com/technetwork/java/jms/index.html

また、標準のJMS APIドキュメントは、TimesTenとともに次の場所にインストールされています。

install_dir/3rdparty/jms1.1/doc/api/index.html

TimesTen JMS/XLAアプリケーションをチューニングしてパフォーマンスを向上させる方法については、「JMS/XLAアプリケーションのチューニング」を参照してください。

注意:
『Oracle TimesTen In-Memory Database開発者および管理者ガイド』で説明されているTimesTenレプリケーション・ソリューションがニーズを満たさない場合、JMS/XLAを使用してカスタム・データ・レプリケーション・ソリューションを構築できます。

この章の内容は次のとおりです。

- JMS/XLAの概念

- JMS/XLAとOracle GDKの依存性

- XLAへの接続

- 表への更新の監視

- 更新の受信および処理

- JMS/XLAアプリケーションの終了

- レプリケーション・メカニズムとしてのJMS/XLAの使用

JMS/XLAの概念

Javaアプリケーションは、JMS/XLA APIを使用してTimesTenからイベント通知を受信できます。JMS/XLAは、JMSパブリッシュ・サブスクライブ・インタフェースを使用してXLA更新へのアクセスを提供します。

XLAへの接続を提供するJMS Sessionインスタンスを確立して永続サブスクライバ(TopicSubscriber)を作成し、更新をサブスクライブします。このサブスクライバを使用してメッセージを同時に受信および処理したり、リスナー(MessageListener)を実装して非同期に更新を処理できます。

JMS/XLAは、ローカル・データベースを監視するアプリケーション用に設計されています。TimesTenおよび通知を受信するアプリケーションは、同じシステム上に存在している必要があります。

注意:
JMS/XLA APIは、XLAのラッパーです。XLAによって更新レコードがトランザクション・ログ・バッファまたはトランザクション・ログ・ファイルから直接取得されるため、それらの更新レコードは読み取られるまで使用可能です。XLAを使用すると、複数のリーダーでトランザクション・ログの更新に同時にアクセスできます。
XLAの詳細は、『Oracle TimesTen In-Memory Database C開発者ガイド』のXLAおよびTimesTenのイベント管理に関する説明を参照してください。

この項の内容は次のとおりです。

- XLAでレコードをトランザクション・ログから読み取る方法

- XLAおよびマテリアライズド・ビュー

- XLAブックマーク

- JMS/XLA構成ファイルおよびXLAトピック

- XLA更新

- XLA応答モード

- アクセス制御がXLAに与える影響

- XLAの制限事項

XLAでレコードをトランザクション・ログから読み取る方法

アプリケーションによってデータベースが変更されると、TimesTenは、データへの変更およびトランザクション・コミットなどの他のイベントを示すトランザクション・ログ・レコードを生成します。

生成される新しいトランザクション・ログ・レコードは、常にトランザクション・ログ・バッファの最後に書き込まれます。トランザクション・ログ・レコードは、メモリ内のログ・バッファからディスク上のトランザクション・ログ・ファイルへ定期的に一括でフラッシュされます。

アプリケーションでは、XLAを使用してデータベースに対する変更のトランザクション・ログを監視できます。XLAは、トランザクション・ログ全体を読み取り、ログ・レコードをフィルタ処理し、目的の表および列への変更が含まれているトランザクション・レコードのリストをXLAアプリケーションに配信します。

XLAは、レコードをディスクリート・トランザクションにソートします。複数のアプリケーションが同時にデータベースを更新している場合、異なるアプリケーションのトランザクション・ログ・レコードがトランザクション・ログに交互配置されます。

XLAは、特定のトランザクションに関連するすべてのトランザクション・ログ・レコードを透過的に抽出し、それらを連続するリストにしてアプリケーションに配信します。

コミット済のトランザクションのレコードのみが返されます。コミット済のレコードは、最後のコミット・レコードがトランザクション・ログに書き込まれる順序で返されます。コミットされていないデータベースへの変更に関連するレコードは、XLAによってフィルタ処理されます。

変更が行われ、その後にロールバックされた場合、XLAは強制終了されたトランザクションのレコードをアプリケーションに配信しません。

XLAの基本的な概念の多くを示すトランザクション・ログの例を、次の図3-1および例3-1で検討してください。

図3-1 トランザクション・ログから抽出されるレコード

例3-1 トランザクション・ログ・レコードの読取り

この例では、トランザクション・ログに次のレコードが含まれています。

CT1: アプリケーションCは、表Wの行1を値7.7で更新。
BT1: アプリケーションBは、表Xの行3を値2で更新。
CT2: アプリケーションCは、表Wの行9を値5.6で更新。
BT2: アプリケーションBは、表Yの行2を値XYZで更新。
AT1: アプリケーションAは、表Zの行1を値3で更新。
AT2: アプリケーションAは、表Zの行3を値4で更新。
BT3: アプリケーションBがトランザクションをコミット。
AT3: アプリケーションAがトランザクションをロールバック。
CT3: アプリケーションCがトランザクションをコミット。

表W、YおよびZへの変更を検出するように設定されているXLAアプリケーションでは次のようになります。

BT2およびBT3: 表Yの行2を値XYZで更新し、コミット。
CT1: 表Wの行1を値7.7で更新。
CT2およびCT3: 表Wの行9を値5.6で更新し、コミット。

この例は、次のことを示します。

- アプリケーションBおよびアプリケーションCのトランザクション・レコードがすべて書き込まれます。

- トランザクション・ログでは、アプリケーションCのレコードがアプリケーションBのレコードより前に書き込まれますが、アプリケーションBのコミット(BT3)はアプリケーションCのコミット(CT3)より前に書き込まれます。その結果、アプリケーションBのレコードはアプリケーションCのレコードより先にXLAアプリケーションに返されます。

- XLAは表Xへの変更を検出するように設定されていないため、アプリケーションBによる表Xへの更新(BT1)は示されません。

- アプリケーションAによる表Zへの更新(AT1およびAT2)は、コミットされずにロールバックされたため(AT3)示されません。

XLAおよびマテリアライズド・ビュー

XLAを使用すると、表およびマテリアライズド・ビューの両方への変更を追跡できます。マテリアライズド・ビューによって、複数のディテール表内の選択した行および列への変更を追跡できる単一のソースが提供されます。マテリアライズド・ビューがない場合は、XLAアプリケーションで、すべてのディテール表の更新レコード(アプリケーションにとって重要ではない行および列への更新が反映されているレコードを含む)に対して監視およびフィルタ処理を行う必要があります。

通常、表に対する変更を追跡するためのXLAメカニズムと、マテリアライズド・ビューに対する変更を追跡するXLAメカニズムとの間に、処理上の違いはありません。ただし、非同期マテリアライズド・ビューの場合、非同期ビューに関するXLA通知の順序が、関連付けられているディテール表に関する順序、または同期ビューに関する順序と同じとはかぎらないことに注意してください。たとえば、ディテール表に対する挿入が2つある場合、非同期マテリアライズド・ビューでは、これらの2つが逆の順序で実行される可能性があります。また、更新が、削除に続く挿入としてXLAによって扱われることがあったり、複数の操作(複数の挿入や複数の削除)を組み合せて1つの操作にされることがあります。正確な順序に依存するアプリケーションでは、非同期のマテリアライズド・ビューを使用しないでください。

マテリアライズド・ビューの詳細は、次を参照してください。

- 『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のCREATE MATERIALIZED VIEWに関する項

- 『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のマテリアライズド・ビューの理解に関する項

XLAブックマーク

XLAブックマークは、トランザクション・ログ内のXLAサブスクライバ・アプリケーションの読取り位置にマークを付けます。ブックマークによって永続サブスクリプションが容易になり、アプリケーションはトピックから切断した後、読取りを中断した時点から、更新の受信を継続するために再接続できます。

この項の以降の内容は次のとおりです。

- ブックマークの使用方法

- レプリケート済ブックマーク

- XLAブックマークおよびトランザクション・ログの保持

ブックマークの使用方法

XLAのメッセージ・コンシューマを作成する場合は、永続TopicSubscriberを使用します。サブスクライバを作成するときに指定するサブスクリプション識別子は、XLAブックマーク名として使用されます。表に対するXLAサブスクリプションを開始および停止するためにJDBCを介してttXlaSubscribeおよびttXlaUnsubscribe組込みプロシージャを使用する場合は、使用するブックマークの名前を明示的に指定します。

応答を受信すると、ブックマークは最終読取り位置にリセットされます。更新メッセージが確認される方法の詳細は、「XLA応答モード」を参照してください。

JMS Sessionオブジェクトでunsubscribe()をコールすることによって、永続サブスクリプションを削除できます。これにより、対応するXLAブックマークが削除され、再接続するときに新規のサブスクリプションが強制的に作成されます。詳細は、「ブックマークの削除」を参照してください。

使用中は、ブックマーク・サブスクリプションの変更はできません。サブスクリプションの変更には、メッセージ・コンシューマをクローズしてから、ttXlaSubscribeおよびttXlaUnsubscribeを使用してサブスクリプションを変更して、その後メッセージ・コンシューマをオープンする必要があります。

注意:
ttXlaBookmarkCreate TimesTen組込みプロシージャを使用して、ブックマークを作成することもできます。このファンクションの詳細は、『Oracle TimesTen In-Memory Databaseリファレンス』のttXlaBookmarkCreateに関する項を参照してください。

レプリケートされるブックマーク

アクティブ・スタンバイ・ペア・レプリケーション・スキームを使用している場合、jmsxla.xmlファイル(「JMS/XLA構成ファイルおよびトピック」を参照)内の<topic>要素のreplicatedBookmark属性に基づいたレプリケートされるブックマークを使用することができます。レプリケートされるブックマークでは、ブックマークへの操作が必要に応じてスタンバイ・データベースにレプリケートされるため、スタンバイに対する必要な書き込み権限があることを想定しています。これにより、フェイルオーバーが発生した場合、より効率的にブックマークの位置をリカバリできます。

レプリケートされたブックマークを使用する際には、次の順で手順を実行する必要があります。

1. アクティブ・スタンバイ・ペアのレプリケーション・スキームを作成します。(これはcreate active standby pair操作、またはクラスタウェア管理環境のttCWAdmin -createコマンドによって行われます。)

2. ブックマークを作成します。

3. ブックマークをサブスクライブします。

4. アクティブ・スタンバイ・ペアを起動します(このとき、スタンバイへの複製が発生し、レプリケーションが始まります)。(これはttRepAdmin -duplicateコマンド、またはクラスタウェア管理環境のttCWAdmin -startコマンドによって行われます。)

注意:

- あるいは、ttXlaBookmarkCreateを使用してブックマークを作成する場合、このファンクションには、レプリケートされるブックマークを指定するためのパラメータがあります。

- レプリケートされたブックマークをJMS/XLA構成ファイルで指定すると、アプリケーションの起動時にJMS/XLAがブックマークを作成し、ブックマークにサブスクライブします。(「JMS/XLA構成ファイルおよびXLAトピック」も参照してください。)

次の点に注意してください。

- スタンバイ・データベースでのブックマークの位置は、アクティブ・データベースでのブックマークの位置に非常に近くなりますが、応答処理のレプリケーションは非同期に行われるため、応答処理の実行頻度によっては、フェイルオーバーの発生時に更新の重複を示す小さなウィンドウが表示されることがあります。

- レプリケートされるブックマークが存在していても、アクティブ・スタンバイ・ペア・スキームは削除できます。ブックマークはその時点でレプリケートされなくなりますが、削除はされません。続けてアクティブ・スタンバイ・ペア・スキームを再度有効にすると、これらのブックマークは自動的にスキームに追加されます。

- レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。

- アクティブ・データベースにあるレプリケートされるブックマークのみ、読み取りまたは応答が可能です。レプリケートされるブックマークに応答するたびに、その応答操作がスタンバイ・データベースに非同期にレプリケートされます。

XLAブックマークおよびトランザクション・ログの保持

XLAの使用時、XLAブックマークが進行するまで、TimesTenトランザクション・ログ・ファイルは保持されることを認識しておく必要があります。この保持により、XLAによって必要がないと判断されるまで、トランザクション・ログ・ファイルはパージされません。XLAアプリケーションが予期せず終了したり、そのブックマークの削除や変更トラッキングの無効化を行わずに切断した場合などに、ブックマークが固まってしまうと、ログは保持されたままになり、トランザクション・ログ・ファイルが過度に蓄積される場合があります。この蓄積により、ディスク領域が一杯になる場合があります。

この状況の監視および解決方法の詳細は、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のトランザクション・ログ・ファイルの蓄積の監視に関する説明を参照してください。

JMS/XLA構成ファイルおよびXLAトピック

XLAに接続するには、特定のデータベースに対応するJMS Topicオブジェクトへの接続を確立します。JMS/XLA構成ファイルでは、トピック名とデータベース間のマッピングが提供されます。

トピックを指定する際、<topic>要素にreplicatedBookmark="yes"と設定すると、レプリケートされるブックマークを指定できます。デフォルトの設定は"no"です。「XLAブックマーク」を参照してください。

デフォルトでは、JMS/XLAは、現在の作業ディレクトリでjmsxla.xmlという構成ファイルを検索します。そのファイルに別の名前または場所を使用する場合は、InitialContextクラスに環境変数の一部として指定し、その場所をクラスパスに追加する必要があります。

例3-2 JMS/XLA構成ファイルの指定

次のコードは、構成ファイルをInitialContextクラスの環境変数の一部として指定します。

Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"com.timesten.dataserver.jmsxla.SimpleInitialContextFactory");
env.put(XlaConstants.CONFIG_FILE_NAME, "/newlocation.xml");
InitialContext ic = new InitialContext(env);

XlaConstants.CONFIG_FILE_NAMEが設定されている場合、JMS/XLA APIでは、クラス・ローダーを使用してJMS/XLA構成ファイルを検索します。この例では、JMS/XLA APIは、CLASSPATH環境変数で指定されている場所と、CLASSPATH変数で指定されているJARファイル内の最上位のディレクトリにあるnewlocation.xmlファイルを検索します。

また、JMS/XLA構成ファイルは、次のようにサブディレクトリに配置することもできます。

env.put(XlaConstants.CONFIG_FILE_NAME,
"/com/mycompany/myapplication/deepinside.xml");

この場合、JMS/XLA APIは、CLASSPATH環境変数で指定されている場所およびCLASSPATH変数で指定されているjarファイル内の両方のcom/mycompany/myapplicationサブディレクトリで、deepinside.xmlファイルを検索します。

JMS/XLA APIでは、最初に見つかった構成ファイルを使用します。

例3-3 構成ファイル内のトピックの定義

構成ファイル内のトピック定義は、名前、接続文字列、および1回で取得する更新数を指定するプリフェッチ値で構成されています。

たとえば、この構成では、DemoDataStoreトピックがTestDB DSNにマップされています。

<xlaconfig>
<topics>
<topic name="DemoDataStore"
connectionString="DSN=TestDB"
xlaPrefetch="100" />
</topics>
</xlaconfig>

例3-4 レプリケートされるブックマークを使用するトピックの定義

レプリケートされるブックマークを使用するかどうかを、トピック定義で指定することもできます。レプリケートされるブックマークを前述の例に使用すると次のようになります。

<xlaconfig>
<topics>
<topic name="DemoDataStore"
connectionString="DSN=TestDB"
xlaPrefetch="100" replicatedBookmark="yes" />
</topics>
</xlaconfig>

XLA更新

アプリケーションは、JMS MapMessageオブジェクトとしてXLA更新を受け取ります。MapMessageオブジェクトには、XLA更新ヘッダー内のフィールドに対応する一連の名前および値のペアが含まれています。

MapMessage取得メソッドを使用してメッセージ・フィールドにアクセスできます。getMapNames()メソッドは、メッセージ内のすべてのフィールドの名前を含むEnumerationオブジェクトを返します。メッセージの個々のフィールドを名前ごとに取得できます。予約されたすべてのフィールド名は、__TYPEのように2つのアンダースコアで始まります。

すべての更新メッセージには、メッセージに含まれている更新のタイプを示す__TYPEフィールドがあります。タイプは、整数値で指定されています。整数タイプと比較するために、com.timesten.dataserver.jmsxla.XlaConstantsに定義されている定数を使用します。表3-1に、サポートされているタイプを示します。

表3-1 XLA更新タイプ

更新タイプ

説明

INSERT

行が追加されました。

UPDATE

行が変更されました。

DELETE

行が削除されました。

COMMIT_ONLY

トランザクションがコミットされました。

CREATE_TABLE

表が作成されました。

DROP_TABLE

表が削除されました。

CREATE_INDEX

索引が作成されました。

DROP_INDEX

索引が削除されました。

ADD_COLUMNS

新規の列が表に追加されました。

DROP_COLUMNS

列が表から削除されました。

CREATE_VIEW

マテリアライズド・ビューが作成されました。

DROP_VIEW

マテリアライズド・ビューが削除されました。

CREATE_SEQ

順序が作成されました。

DROP_SEQ

順序が削除されました。

CREATE_SYNONYM

順序が作成されました。

DROP_SYNONYM

順序が削除されました。

TRUNCATE

表内のすべての行が削除されています。

XLA更新メッセージの内容の詳細は、「JMS/XLA MapMessageの内容」を参照してください。

XLA応答モード

XLAの応答のメカニズムでは、アプリケーションのメッセージの受信だけでなく、メッセージの正常な処理も確認するように設計されています。永続的に更新を応答すると、アプリケーションのXLAブックマークは、読み取られた最終レコードにリセットされます。これにより、以前に返されたレコードが再読み取りされないようになり、アプリケーションがXLAに再接続する場合にブックマークが再利用されるときに、アプリケーションがレコードの新しいバッチのみを受信するようになります。

JMS/XLAは、XLA更新メッセージに自動的に応答することも、応答するメッセージを明示的に選択することもできます。Sessionオブジェクトを作成したときに、更新の応答方法を指定します。

JMS/XLAでは、次の3つの応答方法がサポートされています。

- AUTO_ACKNOWLEDGE: このモードでは、更新は受信時、自動的に応答されます。各メッセージは1回のみ配信されます。同じメッセージは繰り返し送信されないため、アプリケーションに障害が発生すると、メッセージが消失することがあります。メッセージは必ず個々に配信されて応答されるため、JMS/XLAでは複数のレコードをプリフェッチしません。トピック内のxlaprefetch属性は無視されます。

- DUPS_OK_ACKNOWLEDGE: このモードでは、更新は自動的に応答されますが、アプリケーションに障害が発生すると、同じメッセージが繰り返し配信されることがあります。JMS/XLAはトピックに対して指定されているxlaprefetch属性に基づいてレコードをプリフェッチし、プリフェッチされたブロック内の最終レコードが読み取られると応答を送信します。プリフェッチされたすべてのレコードを読み取る前にアプリケーションに障害が発生すると、ブロック内のすべてのレコードは、アプリケーションの再起動時にアプリケーションに渡されます。
xlaprefetchの設定例は、「JMS/XLA構成ファイルおよびトピック」を参照してください。

- CLIENT_ACKNOWLEDGE: このモードでは、アプリケーションはMapMessageへのacknowledge()をコールすることによって更新メッセージの受信を確認します。JMS/XLAはトピックに指定されているxlaprefetch属性に基づいてレコードをプリフェッチします。

次の例では、応答モードを設定します。

Session session = connection.createSession (false, Session.CLIENT_ACKNOWLEDGE);

「更新確認の頻度の減少」も参照してください。

更新のプリフェッチ

複数の更新レコードを一度にプリフェッチする処理は、XLAから各更新レコードを個々に取得する処理より効率的です。AUTO_ACKNOWLEDGEモードを使用すると、更新がプリフェッチされないため、他のモードよりも時間がかかります。可能な場合は、更新を重複して行うことができるようにアプリケーションを設計すると、DUPS_OK_ACKNOWLEDGEの使用、または明示的な更新の確認が可能になります。各メッセージを個々に確認しないようにできるかぎり、通常は明示的な更新の確認によって、最高のパフォーマンスを得ることができます。

更新の確認

XLA更新に明示的に応答するには、更新メッセージでacknowledge()をコールします。メッセージを確認すると、暗黙的に以前のすべてのメッセージを確認します。通常は、確認と確認の間に、複数の更新メッセージを受信および処理します。CLIENT_ACKNOWLEDGEモードを使用していて、永続サブスクリプションを将来再利用する場合は、終了する前に、acknowledge()をコールして最後に読み取られた位置にブックマークを再設定する必要があります。

アクセス制御がXLAに与える影響

「アクセス制御のためのTimesTen機能の検討」では、TimesTenアクセス制御がデータベースの操作に与える影響の概要を提供しています。アクセス制御は、XLAに次のような影響を与えます。

- XLA機能を実行するには、システム権限XLAが必要です。これには、TimesTenにXLAリーダーとして接続して(これにはCREATE SESSION権限も必要)、ttXlaBookmarkCreate、 ttXlaBookmarkDelete、ttXlaSubscribeおよびttXlaUnsubscribe TimesTen XLA組込みプロシージャ(『Oracle TimesTen In-Memory Databaseリファレンス』の組込みプロシージャに関する説明を参照)を実行することも含まれます。

- XLA 権限を持つユーザーは、SELECT ANY TABLE、SELECT ANY VIEWおよびSELECT ANY SEQUENCEのシステム権限と同等の操作を実行できます。

XLAの制限事項

TimesTenのJMS/XLAを使用する際は、XLAの次の制限事項に注意する必要があります。

- JMS/XLAは、TimesTenでサポートされているすべてのプラットフォームで使用できます。ただし、異なるプラットフォーム間、または同じプラットフォームの32ビットと64ビットとの間でのデータの転送はXLAではサポートされていません。

- LOBに対するJMS/XLAサポートは限定されています。詳細は、「表への更新の監視」を参照してください。

- JMS/XLAでは、ドライバ・マネージャ・ライブラリまたはクライアント/サーバー・ライブラリにリンクされたアプリケーションはサポートされていません。

- XLAリーダーは、インメモリー・コラム圧縮を使用する表はサブスクライブできません。

- Oracle Databaseに対する変更トラッキング・トリガーでは、自動リフレッシュ・キャッシュ・グループの列レベルでの解決は行いません。(これは非常に高コストになります。)そのため、自動リフレッシュ機能は行のすべての列を更新し、実際にはすべての列のデータが変更されていない場合でも、XLAではすべての列が変更されたというレポートのみが行われます。

JMS/XLAとOracle GDKの依存性

JMS/XLA APIでは、DatabaseCharacterSet属性で指定されているデータベース・キャラクタ・セットからUTF-16エンコーディングに変換するために、Oracle Globalization Development Kit(GDK)の一部であるorai18n.jarを使用します。JMS/XLA APIは、TimesTenのリリースごとに固有のバージョンのGDKをサポートしています。JMS/XLAによって、JVMにロードされている以外のバージョンのGDKが検出されると、重大な警告が表示され、処理が続行されます。次のコマンドを入力すると、JMS/XLAでサポートされているGDKのバージョンを確認できます。

$ cd install_dir/lib
$ java -cp ./orai18n.jar oracle.i18n.util.GDKOracleMetaData -version

「Javaアプリケーションのコンパイル」も参照してください。

XLAへの接続

更新を受信するためにXLAに接続するには、接続を作成するためにJMS接続ファクトリを使用します。次に、この接続を使用してセッションを確立します。更新の処理を開始する準備ができたら、接続でstart()をコールしてメッセージの配信を有効にします。syncJMSクイック・スタート・デモから、次の例3-5でこれを示します。

例3-5 XLAへの接続

/* JMS connection */
private javax.jms.TopicConnection connection;
/* JMS session */
private TopicSession session;
...
// get Connection
Context messaging = new InitialContext();
TopicConnectionFactory connectionFactory =
(TopicConnectionFactory)messaging.lookup("TopicConnectionFactory");
connection = connectionFactory.createTopicConnection();
connection.start();
...
// get Session
session = connection.createTopicSession(false, Session.AUTO_ACKNOWLEDGE);

表への更新の監視

更新の受信を開始する前に、変更の監視対象となる表を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. TopicSubscriberにMessageListenerを登録します。

4. 接続を開始します。

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

5. メッセージを受信するまで待機します。アプリケーションがメイン・スレッド内で行う処理が他にない場合は、Objectメソッドwait()をコールしてメッセージを待機できます。

更新がパブリッシュされると、MessageListenerメソッドonMessage()がコールされ、メッセージがMapMessageインスタンスとして渡されます。

SYS.XLASUBSCRIPTIONSシステム表を確認することで、アプリケーションで表のサブスクリプションを検証できます。

注意:
XLAでのLOBのサポートは、限定されています。BLOBフィールドにはMapMessageメソッドのgetBytes()を使用し、CLOBまたはNCLOBフィールドにはgetString()を使用することによって更新メッセージでLOBフィールドにアクセスできますが、これらのフィールドには長さが0のデータが含まれる場合があります(または値が実際NULLの場合はnullデータが含まれます)。

例3-6(asyncJMSクイック・スタート・デモ)では、リスナーを使用して更新を非同期に処理します。

例3-6 リスナーを使用した更新の非同期処理

MyListener myListener = new MyListener(outStream);

outStream.println("Creating consumer for topic " + topic);
Topic xlaTopic = session.createTopic(topic);
bookmark = "bookmark";
TopicSubscriber subscriber = session.createDurableSubscriber(xlaTopic, bookmark);

// After setMessageListener() has been called, myListener's onMessage
// method is called for each message received.
subscriber.setMessageListener(myListener);

bookmarkは既に存在している必要があります。JDBCおよびttXlaBookmarkCreate組込みプロシージャを使用して、ブックマークを作成できます。また、TopicSubscriberは、永続サブスクライバである必要があります。XLA接続は永続的であるように設計されています。XLAブックマークによって、トピックからの切断が可能になり、更新が中断した位置から更新の受信を開始するために、再度接続することもできます。永続サブスクライバの作成時にサブスクリプション識別子として渡す文字列は、XLAブックマーク名として使用されます。

JMS TopicSessionでunsubscribe()をコールして、アプリケーションの停止時にそのサブスクライバが使用したXLAブックマークを削除できます。これによって、アプリケーションの再起動時に、新しいブックマークが作成されます。

更新を受信すると、MapMessage取得メソッドを使用してメッセージから情報を抽出し、アプリケーションで必要な処理を行うことができます。TimesTen XlaConstantsクラスでは、XLA更新メッセージの処理に使用にするために、更新タイプおよび特別なメッセージ・フィールドの定数が定義されています。

通常、メッセージに含める更新タイプを最初に決定します。MapMessageメソッドgetInt()を使用して__TYPEフィールドの内容を取得し、XlaConstantsクラスで定義されている数値定数とその値を比較します。

例3-7では(asyncJMSクイック・スタート・デモ)、メソッドonMessage()はMapMessageオブジェクトから更新タイプを抽出し、更新が示している処理を表示します。

例3-7 更新タイプの決定

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()をコールします。メッセージの個々のフィールドを名前ごとに取得できます。

例3-8では(asyncJMSクイック・スタート・デモ)、列名を使用して、挿入、更新および削除メッセージから列値を抽出します。

例3-8 列値の抽出

/* 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アプリケーションがトランザクション・ログからの読取りを終了した場合は、XLA接続をクローズして不要なブックマークを削除し、明示的にサブスクライブした表をサブスクライブ解除して、正常に終了する必要があります。

接続のクローズ

XLAへの接続をクローズするには、Connectionオブジェクトでclose()をコールします。

接続がクローズされた後、その接続、セッションまたはサブスクライバを使用しようとすると、IllegalStateExceptionエラーになります。その接続から受信したメッセージを継続して使用できますが、接続がクローズされた後、受信したメッセージのacknowledge()メソッドをコールすることはできません。

ブックマークの削除

停止時にXLAブックマークを削除するかどうかは、任意に選択できます。ブックマークを削除すると、トランザクション・ログ内の未読の更新レコードに関連するディスク領域を解放できます。

ブックマークを削除しない場合は、永続サブスクライバで再利用できます。永続サブスクライバが再接続するときにブックマークが使用可能な場合、サブスクライバは、以前の接続が終了した後に発行されたすべての未確認の更新を受信します。アプリケーションが読取りを行わないブックマークがある場合は、トランザクション・ログが増大し続け、データベースが消費するディスク領域が増加するので注意してください。

ブックマークを削除するには、JMS Sessionでunsubscribe()をコールすることにより、ttXlaBookmarkDelete組込みプロシージャが起動され、XLAブックマークが削除されます。

注意:
レプリケーション・エージェントが実行されている間は、レプリケートされるブックマークを削除できません。

表からのサブスクライブ解除

表に対するXLAパブリッシングをオフにするには、ttXlaUnsubscribe組込みプロシージャを使用します。ttXlaSubscribeを使用して表に対するXLAパブリッシングを有効にする場合は、アプリケーションを停止するときにttXlaUnsubscribeを使用して表からのサブスクライブ解除を行う必要があります。

注意:
表を削除する場合は、まず表からサブスクライブ解除します。

表からのサブスクライブ解除を行う場合は、次のように表を追跡するときに使用される表の名前とブックマークの名前を指定します。

ttXlaUnsubscribe(user.table, mybookmark)

たとえば、CallableStatementオブジェクトでttXlaUnSubscribeをコールするには、次の例のようにします。

例3-9 表からのサブスクライブ解除

Connection con;
CallableStatement cStmt;
...
cStmt = con.prepareCall("{call ttXlaUnSubscribe(user.table, mybookmark)}");
cStmt.execute();

JavaアプリケーションでTimesTen組込みプロシージャを使用する場合の詳細は、「プロシージャおよびファンクションを実行するためのCALLの使用」を参照してください。

レプリケーション・メカニズムとしてのJMS/XLAの使用

『Oracle TimesTen In-Memory Database開発者および管理者ガイド』で説明しているTimesTenでのレプリケーションは、多くのお客様のニーズを満たしますが、JMS/XLAを使用してデータベース間で更新をレプリケートすることも可能です。この方法で独自のレプリケーション・スキームをJMS/XLAに加え実装することはかなり複雑ですが、なんらかの理由でTimesTenでのレプリケーションが実現不能な場合は検討できます。

ターゲット・データベースへのJMS/XLAメッセージの適用

ソース・データベースでJMS/XLAメッセージが作成されます。このメッセージをターゲット・データベースに適用するには、メッセージからXLA記述子を抽出する必要があります。MapMessageインタフェースを使用して更新記述子を抽出します。

MapMessage message;
/*
*...other code
*/
try {
byte[]updateMessage=
mapMessage.getBytes(XlaConstants.UPDATE_DESCRIPTOR_FIELD);
}
catch (JMSException jex){
/*
*...other code
*/
}

ターゲット・データベースは、ソース・データベースとは別のシステムにインストールできます。更新記述子はバイト配列として返され、ネットワーク送信のためにシリアライズすることができます。

ソース・データベースからのオブジェクトを適用するために、ターゲット・データベースを表すターゲット・データベース・オブジェクトを作成する必要があります。TargetDataStoreImplクラスのインスタンスとして、myTargetDataStoreというターゲット・データベース・オブジェクトを作成します。次に例を示します。

TargetDataStore myTargetDataStore=
new TargetDataStoreImpl("DSN=sampleDSN");

TargetDataStoreメソッドapply()を使用して、myTargetDataStoreにメッセージを適用します。次に例を示します。

myTargetDataStore.apply(updateDescriptor);

デフォルトでは、TimesTenは、更新を適用する前にターゲット・データベース上の競合を確認します。ターゲット・データベースに更新よりも遅い情報が含まれる場合、TargetDataStoreでは例外がスローされます。TimesTenで競合を確認しない場合は、TargetDataStoreメソッドsetUpdateConflictCheckFlag()を使用して動作を変更します。

デフォルトでは、TimesTenは、更新記述子に含まれているコミット・フラグとトランザクション境界に基づいてデータベースに対する更新をコミットします。アプリケーションで手動コミットを実行する場合は、setAutoCommitFlag()メソッドを使用して自動コミット・フラグを変更します。myTargetDataStoreに対して手動コミットを実行するには、次のコマンドを使用します。

myTargetDataStore.commit();

更新アプリケーションでエラーが発生した場合は、ロールバックを実行できます。myTargetDataStoreに対して次のコマンドを使用します。

myTargetDataStore.rollback();

次のコマンドを使用して、myTargetDataStoreをクローズします。

myTargetDataStore.close();

TargetDataStoreインタフェースの詳細は、「JMS/XLAレプリケーションAPI」を参照してください。

TargetDataStoreのエラー・リカバリ

TargetDataStoreを起動すると、一時的なエラーと永続的なエラーが発生する可能性があります。

一時的なエラーが発生すると、TargetDataStoreメソッドによって0(ゼロ)以外の値が返されます。アプリケーションは処理を再試行することができ、再適用する必要がある更新記述子を監視します。一時的なXLAのエラーの詳細は、『Oracle TimesTen In-Memory Database C開発者ガイド』のXLAのエラーの処理に関する項を参照してください。

永続的なエラーに対しては、TargetDataStoreメソッドによってJMSExceptionオブジェクトが返されます。アプリケーションが永続的なエラーを受信すると、データベースが有効かどうかを確認する必要があります。データベースが無効な場合、ターゲット・データベース・オブジェクトを閉じ、新しいものを作成する必要があります。その他のタイプの永続的なエラーには、手動での操作が必要になる場合があります。

次の例に、TargetDataStoreオブジェクトからエラーをリカバリする方法を示します。

例3-10 エラーのリカバリ

TargetDataStore theTargetDataStore;
byte[] updateDescriptor;
int rc;

// Other code
try {
...
if ( (rc = theTargetDataStore.apply(updateDescriptor) ) == 0 ) {
// Apply successful.
}
else {
// Transient error. Retry later.
}
}
catch (JMSException jex) {
if (theTargetDataStore.isDataStoreValid() ) {
// Database valid; permanent error that may need Administrator intervention.
}
else {
try {
theTargetDataStore.close();
}
catch (JMSException closeEx) {
// Close errors are not usual. This may need Administrator intervention.
}
}

4 分散トランザクション処理: JTA

ここでは、TimesTenに実装されているJavaトランザクションAPI(JTA)について説明します。

TimesTenに実装されているJava JTAインタフェースは、Javaアプリケーション、アプリケーション・サーバーおよびトランザクション・マネージャを有効化して、分散トランザクション処理(DTP)環境でTimesTenリソース・マネージャを使用することを目的にしています。TimesTenのこの実装はOracle WebLogic Serverで使用するためにサポートされています。

この章では、TimesTenにおけるJTAの実装に固有の情報を説明します。また、次のドキュメントもあわせて参照してください。

- JTAおよびJDBCのドキュメントは、次の場所から利用可能です。
http://www.oracle.com/technetwork/java/javaee/tech/

http://www.oracle.com/technetwork/java/javase/tech/

- WebLogicのドキュメントは、次の場所から利用可能です。

http://www.oracle.com/technetwork/middleware/weblogic/documentation

TimesTen JTAは、X/Open XA標準のTimesTen実装の最初の部分であるため、ここでの説明の多くは基本的なXA機能に関することです。『Oracle TimesTen In-Memory Database C開発者ガイド』のXAの分散トランザクション処理に関する項も参照してください。

この章の内容は次のとおりです。

- JTAの概要

- TimesTenでのJTAの使用

- JTA APIの使用

重要:

- TimesTen XAの実装は、TimesTen Application-Tier Database Cache (TimesTen Cache)では動作しません。キャッシュ・エージェントが実行されていると、XAトランザクションの開始に失敗します。

- レプリケーションが有効化されていると、XAトランザクションは実行できません。

- XAトランザクション内では、DDL文は実行しないでください。

JTAの概要

この項では、次のXA概念の概要を簡単に説明します。

- X/Open DTPモデル

- 2フェーズ・コミット

X/Open DTPモデル

図4-1 にX/Open DTPモデルによって定義されるインタフェースを示します。

図4-1 分散トランザクション処理モデル

TXインタフェースとは、トランザクション・マネージャとの通信に使用するアプリケーションです。この図はグローバル・トランザクションをトランザクション・マネージャに伝達するアプリケーションを示しています。DTPモデルでは、トランザクション・マネージャは、各グローバル・トランザクションを複数のブランチに分割し、分割したグローバル・トランザクションを別々のリソース・マネージャのサービスに分散させます。トランザクション・マネージャは、JTAインタフェースを使用して、各トランザクション・ブランチと適切なリソース・マネージャを調整します。

TimesTen JTAのコンテキストでは、リソース・マネージャは、TimesTenデータベースのコレクションの場合と、JTAをサポートする他の商用データベースと組み合せたデータベースのコレクションの場合があります。

TXおよびJTAインタフェースで提供されるグローバル・トランザクション制御は、ネイティブのJDBCインタフェースで提供されるローカル・トランザクション制御とは異なります。一般に、ローカル・トランザクションおよびグローバル・トランザクションには別々の接続を使用することをお薦めします。アプリケーションは、TimesTenリソース・マネージャに対する接続ハンドルを取得して、同じ接続上でローカル・トランザクションおよびグローバル・トランザクションの両方を開始できます。

2フェーズ・コミット

JTAの実装においてトランザクション・マネージャは、グローバル・トランザクションの分散したブランチを2フェーズ・コミット・プロトコルを使用してコミットします。

1. 第1フェーズでは、トランザクション・マネージャは、グローバル・トランザクションの各ブランチがコミット可能であることを確認し、保証するために、各リソース・マネージャに対してコミットを準備するように指示します。リソース・マネージャがそのブランチをコミットできない場合、トランザクション・マネージャは、第2フェーズでトランザクション全体をロールバックします。

2. 第2フェーズでは、トランザクション・マネージャは、各リソース・マネージャにブランチをコミットするように命令します(第1フェーズでコミットできなかったことがリソース・マネージャにレポートされている場合は、グローバル・トランザクションをロールバックします)。

次の最適化された動作に注意してください。

- トランザクション・マネージャは、グローバル・トランザクションに1つのブランチのみが含まれるように指定した場合、第1フェーズをスキップして、第2フェーズでトランザクションをコミットします。

- グローバル・トランザクション・ブランチが読取り専用で、トランザクション・ログ・レコードが生成されない場合、トランザクション・マネージャは第1フェーズでそのブランチをコミットし、ブランチの第2フェーズをスキップします。

注意:
トランザクション・マネージャは、すべてのブランチを正常にコミットしたときにかぎり、グローバル・トランザクションがコミットされたとみなします。

TimesTenでのJTAの使用

この項では、TimesTenでJTAを使用する際の次の考慮事項について説明します。

- XAに対するTimesTenデータベースの要件

- TimesTenでのグローバル・トランザクションのリカバリ

- TimesTenでのXAエラーの処理

XAに対するTimesTenデータ・ストアの要件

グローバル・トランザクションの一貫性を保証するには、TimesTen XAのトランザクション・ブランチが永続的である必要があります。xa_prepare()、xa_rollback()およびxa_commit()ファンクションのTimesTenの実装では、DurableCommits一般接続属性の設定値またはttDurableCommit組込みプロシージャを使用したかどうかに関係なく、実行された処理をディスクに記録します。障害からのリカバリが必要な場合は、リソース・マネージャおよびTimesTenトランザクション・マネージャの両方に、障害発生時に準備された状態でアクティブだったトランザクション・ブランチに関する一貫性のあるビューが含まれています。

TimesTenでのグローバル・トランザクションのリカバリ

障害発生または予期しない終了の後にデータベースがディスクからロードされてリカバリが行われると、準備されたもののコミットされていないグローバル・トランザクションが保留中(インダウト)の状態のままになります。すべてのインダウト・トランザクションが解決されるまで、通常の処理は行えません。

接続およびリカバリが完了すると、TimesTenはインダウト・トランザクションを確認します。インダウト・トランザクションがない場合は、処理を通常どおり実行します。インダウト・トランザクションがあると、他の接続を作成することはできますが、インダウト・トランザクションが解決されるまでは、これらの接続でのすべての処理が事実上禁止されます。他のすべてのJDBCのコールは次のエラーになります。

Error 11035 - "In-doubt transactions awaiting resolution in recovery must be
resolved first"

インダウト・トランザクションのリストは、xa_recover()のXA実装によって取得した後、XAでxa_commit()、xa_rollback()またはxa_forget()を適切にコールすることによって処理できます。インダウト・トランザクションがすべて消去されると、通常どおりに処理が続行されます。

トランザクション・マネージャでは、接続後にまずxa_recover()をコールする必要があるため、この方法はトランザクション・マネージャで厳密に制御された状態で動作するシステムに適しています。

トランザクション・マネージャを使用できない場合またはインダウト・トランザクションを解決できない場合は、ttXactAdminユーティリティの-HCommitまたは-HAbortオプションを使用して、個々のトランザクション・ブランチを個別にコミットまたは強制終了できます。ただし、これらのttXactAdminオプションにはADMIN権限が必要であることに注意してください。『Oracle TimesTen In-Memory Databaseリファレンス』のttXactAdminに関する項を参照してください。

TimesTenでのXAエラーの処理

XA仕様では、XAインタフェース・コールから返される可能性がある一定のエラーが厳密に定義されています。ODBCのSQLErrorメカニズムは、他の補足情報(ある場合)とともにXAの定義済エラーを返します。

TimesTenのXA関連エラーは、11000番から始まります。エラー11002から11020は、XA標準で定義済のエラーに対応しています。

すべてのエラーの一覧は、『Oracle TimesTen In-Memory Databaseエラー・メッセージおよびSNMPトラップ』の警告とエラーに関する章を参照してください。

JTA APIの使用

TimesTenのJTA実装は、JTA仕様の規定に準拠したAPIを提供します。TimesTenのJTAはJDK 1.4以上のバージョンで動作します。

この項では、JTA APIの使用に関する次の内容について説明します。

- 必要なパッケージ

- TimesTen XAConnectionオブジェクトの作成

- XAResourceおよびConnectionオブジェクトの作成

WebLogicでTimesTen DSNを登録する方法、TimesTenのアプリケーション・サーバーの構成およびオブジェクトリレーショナル・マッピングのフレームワークに関する情報については、TimesTenクイック・スタートを参照してください。「Configuration and Setup」の「Java EE and OR Mapping」をクリックしてください。

必要なパッケージ

TimesTen JDBCおよびXA実装は、次のパッケージから利用可能です。

com.timesten.jdbc.*;
com.timesten.jdbc.xa.*;

アプリケーションは、次の標準パッケージもインポートする必要があります。

import java.sql.*;
import javax.sql.*;
import javax.transaction.xa.*;

TimesTen XAConnectionオブジェクトの作成

XAデータ・ソースへの接続は、XADataSourceオブジェクトを経由して確立されます。TimesTenXADataSourceインスタンスを接続ファクトリとして使用して、データベースにXAConnectionオブジェクトを作成できます。TimesTenXADataSourceはjavax.sql.XADataSourceインタフェースを実装します。

TimesTenXADataSourceインスタンスを新規に作成したら、setUrl()メソッドを使用して、データベースを指定します。

URLは次のようになります。

- 直接接続の場合: jdbc:timesten:direct:DSNname

- クライアント接続の場合: jdbc:timesten:client:DSNname

setUser()メソッドおよびsetPassword()メソッドを任意で使用して、特定のユーザーのIDおよびパスワードを設定することもできます。

注意:
データベースに接続するには、権限が付与されている必要があります。「接続のアクセス制御」を参照してください。

例4-1 TimesTen XAデータ・ソース・オブジェクトの作成

この例では、TimesTenXADataSourceオブジェクトをファクトリとして使用して、新しいTimesTen XAデータ・ソース・オブジェクトを作成します。次に、このTimesTenXADataSourceインスタンスに、TimesTen DSN(dsn1)、ユーザー名(myName)およびパスワード(myPasswd)を識別するURLが設定されます。次に、getXAConnection()メソッドが、xaConnオブジェクトへ接続を返すために使用されます。

TimesTenXADataSource xads = new TimesTenXADataSource();

xads.setUrl("jdbc:timesten:direct:dsn1");
xads.setUser("myName");
xads.setPassword("myPassword");

XAConnection xaConn = null;
try {
xaConn = xads.getXAConnection();
}
catch (SQLException e){
e.printStackTrace();
return;
}

XAデータ・ソース・オブジェクトに対して複数の接続を作成できます。この例では、xaConn2という2つ目の接続を作成します。

XAConnection xaConn  = null;
XAConnection xaConn2 = null;

try {
xaConn  = xads.getXAConnection();
xaConn2 = xads.getXAConnection();
}

例4-2 複数のTimesTen XAデータ・ソース・オブジェクトの作成

この例では、dsn1およびdsn2という名前のデータベース用にTimesTenXADataSourceのインスタンスを2つ作成します。次に、dsn1に1つの接続を作成し、dsn2に2つの接続を作成します。

TimesTenXADataSource xads = new TimesTenXADataSource();

xads.setUrl("jdbc:timesten:direct:dsn1");
xads.setUser("myName");
xads.setPassword("myPassword");

XAConnection xaConn1 = null;
XAConnection xaConn2 = null;
XAConnection xaConn3 = null;

try {
xaConn1 = xads.getXAConnection(); // connect to dsn1
}
catch (SQLException e){
e.printStackTrace();
return;
}

xads.setUrl("jdbc:timesten:direct:dsn2");
xads.setUser("myName");
xads.setPassword("myPassword");

try {
xaConn2 = xads.getXAConnection(); // connect to dsn2
xaConn3 = xads.getXAConnection(); // connect to dsn2
}
catch (SQLException e){
e.printStackTrace();
return;
}

注意:
XAConnectionが確立されると、自動コミットはオフになります。

XAResourceおよびConnectionオブジェクトの作成

getXAConnection()を使用して、XAConnectionオブジェクトを取得した後、XAConnectionメソッドgetXAResource()を使用して、XAResourceオブジェクトを取得して、次にXAConnectionメソッドgetConnection()を使用して、基礎となる接続のConnectionオブジェクトを取得できます。

例4-3 XAリソース・オブジェクトおよび接続の取得

//get an XAResource
XAResource xaRes = null;
try {
xaRes = xaConn.getXAResource();
}
catch (SQLException e){
e.printStackTrace();
return;
}

//get an underlying physical Connection
Connection conn = null;
try {
conn = xaConn.getConnection();
}
catch (SQLException e){
e.printStackTrace();
return;
}

この時点で、同一の接続のconnを、ローカル・トランザクションおよびグローバル・トランザクションの両方に使用できます。ただし、次の点に注意してください。

- グローバル・トランザクションを開始する前に、アクティブなローカル・トランザクションをコミットまたはロールバックする必要があります。そうしないと、XAException例外XAER_OUTSIDEが発生します。

- ローカル・トランザクションを開始する前に、アクティブなグローバル・トランザクションを終了する必要があります。そうしないと、SQLException、「Illegal combination of local transaction and global (XA) transaction.」が表示されます。

5 Javaアプリケーションのチューニング

この章では、TimesTenデータベース上で最適に実行されるようにJavaアプリケーションをチューニングする方法のヒントを示します。より一般的なチューニングのヒントについては、『Oracle TimesTen In-Memory Databaseオペレーション・ガイド』のTimesTen Databaseのパフォーマンス・チューニングに関する項を参照してください。

この章は、次の内容で構成されています。

- JDBCアプリケーションのチューニング

- JMS/XLAアプリケーションのチューニング

JDBCアプリケーションのチューニング

この項では、TimesTen用のJDBCアプリケーションをチューニングする場合に考慮する必要がある一般的な方針について説明します。内容は次のとおりです。

- 準備された文のプールの使用

- バッチ実行にパラメータの配列を使用

- TimesTenデータ行のバルク・フェッチ

- ResultSetメソッドgetString()の限定的使用

- データ型の変換の回避

- 接続、文、結果セットのクローズ

注意:
「TimesTen結果セットの使用: ヒントおよび制限」および「パラメータのバインドと文の実行」の注意も参照してください。

準備された文のプールの使用

TimesTenでは、プールされた接続用に、TimesTen ObservableConnectionDSクラスによる準備された文のプール(JDBC 3.0の仕様を参照)をサポートしています。これは、TimesTenへのConnectionPoolDataSourceの実装です。文のプールは、アプリケーションに対して透過的であることに注意してください。PreparedStatementオブジェクトは同様に使用(文の準備およびクローズを含む)できます。

準備された文のプールを有効化して、ObservableConnectionDSメソッドsetMaxStatements()をコールすることでプールの文の最大数を指定できます。デフォルトの値は0で、準備された文プールを無効化しています。0より大きい任意の整数値を指定すると、その値を文の最大数として、準備された文のプールを有効化します。設定した後、この値は変更しないでください。

最大プール数に達していないかぎり、準備された文またはコール可能な文は作成時にプールされます。Java 6では、文オブジェクトよりsetPoolable(false)をコールすることによって、準備された文またはコール可能な文をプールから削除できます。文は終了するとプールから削除されます。

重要:
準備された文のプールを使用する場合、JDBCは、SQLが(コメントを含めて)同一であれば、オプティマイザ設定などの他の考慮事項に関係なく、その2つの文を同一とみなします。他の点では同一の文に、異なるオプティマイザ・ヒントが適用される可能性がある場合、準備された文のプールは使用しないでください。このシナリオでは、文の実行によって、プールの同一の文が予測不能なオプティマイザ設定で使用されることがあります。

バッチ実行にパラメータの配列を使用

文の実行グループ(バッチとも呼ばれる)を使用してStatementまたはPreparedStatementオブジェクトにaddBatch()およびexecuteBatch()メソッドをコールすることで、パフォーマンスを向上させることができます。

バッチは、INSERT、UPDATE、DELETEまたはMERGEなどの文のセットで構成されます。SELECTなどの結果セットを返す文は、バッチでは使用できません。文オブジェクトよりaddBatch()をコールすると、バッチにSQL文が追加されます。バッチに関連付けられている一連のSQL文は、executeBatch()メソッドによって実行されます。

PreparedStatementオブジェクトの場合、バッチは異なる入力パラメータ値を使用して繰返し実行される1つの文で構成されます。入力値のセットごとに、必要なsetXXX()コールを使用した後に、addBatch()コールを使用して、バッチを作成します。バッチは、executeBatch()メソッドを介して実行されます。

TimesTenでは、TimesTen 11gリリース2(11.2.2)に次のバッチ・サイズを推奨します。

- INSERT文に256

- UPDATE文に31

- DELETE文に31

- MERGE文に31

例5-1 文へのバッチ

// turn off autocommit
conn.setAutoCommit(false);

Statement stmt = conn.createStatement();
stmt.addBatch("INSERT INTO employees VALUES (1000, 'Joe Jones')");
stmt.addBatch("INSERT INTO departments VALUES (260, 'Shoe')");
stmt.addBatch("INSERT INTO emp_dept VALUES (1000, 260)");

// submit a batch of update commands for execution
int[] updateCounts = stmt.executeBatch();
conn.commit ();

例5-2 準備された文へのバッチ

// turn off autocommit
conn.setAutoCommit(false);
// prepare the statement
PreparedStatement stmt = conn.prepareStatement
("INSERT INTO employees VALUES (?, ?)");

// first set of parameters
stmt.setInt(1, 2000);
stmt.setString(2, "Kelly Kaufmann");
stmt.addBatch();

// second set of parameters
stmt.setInt(1, 3000);
stmt.setString(2, "Bill Barnes");
stmt.addBatch();

// submit the batch for execution. Check update counts
int[] updateCounts = stmt.executeBatch();
conn.commit ();

StatementまたはPreparedStatementオブジェクトでは、executeBatch()メソッドは更新回数の配列(前述の例5-1および例5-2のupdateCounts[])と各文の実行の配列の1要素を返します。各要素の値は次のいずれかになります。

- 数字は、対応する文の実行によってデータベース内で影響を受ける行の数を示します

- SUCCESS_NO_INFOは、対応する文の実行に成功したことを示しますが、影響を受けた行数については不明です

- EXECUTE_FAILEDは、対応する文の実行に失敗したことを示します
文の実行がEXECUTE_FAILEDのステータスになると、それ以降、文の実行は試行されません

JDBCバッチ更新機能の使用方法の詳細は、次の場所にある、Javadocのjava.sql.Statementインタフェース(特に、executeBatch()メソッド)に関する情報を参照してください(1つ目はJava 6用で2つ目はJava 5.0用です)。

http://docs.oracle.com/javase/6/docs/api/java/sql/package-summary.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/sql/package-summary.html

注意:
連想配列パラメータは、JDBCのバッチの実行ではサポートされていません(詳細は、「連想配列のバインド」を参照してください)。

TimesTenデータ行のバルク・フェッチ

TimesTenで提供されている拡張を使用すると、アプリケーションで複数のデータ行をフェッチできます。大量のTimesTenデータを取得するアプリケーションの場合、複数行のフェッチによってパフォーマンスを大幅に向上させることができます。ただし、コミット読取り分離レベルが使用される場合は、アプリケーションですべてのデータが取得されるまで、取得されるすべての行にロックが設定されるため、同時実行性は低下します。この機能の詳細は、「複数のデータ行のフェッチ」を参照してください。

ResultSetメソッドgetString()の限定的使用

Javaの文字列は不変的であるため、ResultSetメソッドgetString()は、(基礎となるC文字列からUnicode文字列への変換に加えて、)新しい文字列用の領域を確保する必要があり、高コストのコールとなっています。

また、必要時以外は、byteやintなどの基本的な数値型でgetString()をコールしないでください。たとえば、整数列の場合、getInt()をコールする方が大幅に高速に処理が実行されます。

データ型の変換の回避

TimesTenの命令パスは非常に短いため、データ変換による短時間の遅延によっても、トランザクション時間が大幅に増加する可能性があります。

基礎となるデータベース内のデータのデータ型に対してのResultSetオブジェクトには、適切なgetXXX()メソッドを使用します。たとえば、データのデータ型がDOUBLEである場合、JDBCドライバでのデータ変換を避けるために、getDouble()をコールする必要があります。同様に、SQL文の入力パラメータには、PreparedStatementオブジェクトで、適切なsetXXX()メソッドを使用します。たとえば、PreparedStatementを使用してCHAR列にデータを挿入する場合は、setString()を使用する必要があります。

接続、文、結果セットのクローズ

パフォーマンスを向上させるには、接続、文および結果セット・インスタンスなどのJDBCオブジェクトの使用後は常にクローズします。例5-3に典型的な使用例を示します。

例5-3 接続、文、結果セットのクローズ

Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
// create connections, execute statements, etc.
// Handle any errors
} catch (SQLException ex) {
// See "Handling errors".
}
finally {
// Close JDBC objects such as connections, statements, result sets, etc.
if (rs != null) {
try {
rs.close();
}
catch(SQLException finalex) {
// See "Handling errors".
}
}
if (stmt != null) {
try {
stmt.close();
}
catch(SQLException finalex) {
// See "Handling errors".
}
}
// Always, close the connection to TimesTen
if (conn != null) {
try {
conn.close();
}
catch(SQLException finalex) {
// See "Handling errors".
}
}

JMS/XLAアプリケーションのチューニング

この項では、JMS/XLA APIを使用するアプリケーションに固有のパフォーマンス・チューニングのヒントを示します。JMS/XLAでは、オーバーヘッドが発生するため、C XLA APIを使用した場合より低速となります。C APIでは、レコードがユーザーにバッチで戻されます。JMSモデルでは、オブジェクトがインスタンス化され、MessageListenerメソッドonMessage()に対するコールバックで各レコードが1つずつ示されます。高パフォーマンスのアプリケーションでは、チューニングを行ってこのオーバーヘッドの一部を回避できます。

この項の内容は次のとおりです。

- xlaPrefetchパラメータの設定

- 更新確認の頻度の減少

- 高いイベント率の処理

注意:
JMS/XLAに関連したアクセス制御の考慮事項については、「アクセス制御がXLAに与える影響」を参照してください。

xlaPrefetchパラメータの設定

トランザクション・ログを読み取るJMSレイヤーの基礎となるコードは、オブジェクト/行をユーザーに示す前にできるかぎり多くの行をフェッチ可能な場合、より効率的になります。プリフェッチの量は、xlaPrefetchパラメータが指定されたjmsxla.xml構成ファイルで制御されます。プリフェッチ数は、100、1000などの大きい値に設定します。

更新確認の頻度の減少

JMS/XLAでは、更新の確認によってブックマークが移動し、システム表が更新されます。確認の発行前は、いくつかの更新が検出されるまで待機することで、通常はアプリケーションのパフォーマンスを向上させることができます。次のいずれかのモードで、確認の頻度を制御できます。(関連情報は、「XLA応答モード」を参照してください。)

- DUPS_OK_ACKNOWLEDGEでは、xlaprefetch設定に従ってJMS/XLAはレコードをプリフェッチし、プリフェッチされたブロックの最後のレコードが読み取られると、応答は自動的に送信されます。

- CLIENT_ACKNOWLEDGEでは、希望に応じて、MapMessageインスタンスでacknowledge()メソッドを手動でコールします。

確認の頻度の適切な選択は、アプリケーション・ロジックによって決まります。たとえば、100の更新ごとに確認が正常に使用されてきました。ただし、トレードオフがあることに注意してください。確認はXLAログの保持に影響を与え、確認の頻度が低すぎると、好ましくないログ・ファイルの蓄積につながることがあります。(「XLAブックマークおよびトランザクション・ログの保持」も参照してください。)

注意:
DUPS_OK_ACKNOWLEDGEまたはCLIENT_ACKNOWLEDGEモードでは、リーダー・アプリケーションで同じレコード・セットが複数回戻されることを許容できる必要があります。

高いイベント率の処理

同期インタフェースは、イベント率が低いアプリケーションと、AUTO_ACKNOWLEDGEまたはDUPS_OK_ACKNOWLEDGE応答モードを許容できるアプリケーションにのみ適しています。CLIENT_ACKNOWLEDGE応答モードを必要とするアプリケーションと、イベント率が高いアプリケーションでは、更新を受信するために非同期インタフェースを使用する必要があります。それらのアプリケーションで応答モードとしてCLIENT_ACKNOWLEDGEを使用する場合は、コールバック・スレッド自体のメッセージに応答する必要があります。「更新の受信および処理」を参照してください。

6 JMS/XLAリファレンス

ここでは、JMS/XLA APIに関するリファレンス情報を示します。内容は次のとおりです。

- JMS/XLA MapMessageの内容

- DMLイベント・データの書式

- DDLイベント・データの書式

- データ型のサポート

- イベント処理用のJMSクラス

- JMS/XLAレプリケーションAPI

- JMSのメッセージ・ヘッダー・フィールド

注意:
「アクセス制御がXLAに与える影響」で、TimesTenアクセス制御がXLA機能に与える影響について説明されています。

JMS/XLA MapMessageの内容

javax.jms.MapMessageには、C構造体ttXlaUpdateDesc_tとしてパブリッシュされた、XLA更新ヘッダー内のフィールドに対応する一連の名前および値のペアが含まれています。MapMessageインスタンスに含まれるフィールドは、更新タイプによって異なります。

XLA更新タイプ

JMS/XLA APIで返される各MapMessageには、整数値としてメッセージ内に記述されている更新タイプを示す__TYPE(アンダースコア2つ)という名前と値のペアが1つ以上含まれています。タイプは、整数値で指定されています。整数タイプと比較するために、com.timesten.dataserver.jmsxla.XlaConstantsに定義されている定数を使用します。表6-1に、サポートされているタイプを示します。

表6-1 XLA更新タイプ

タイプ

説明

ADD_COLUMNS

列が追加されたことを示します。

COMMIT_FIELD

コミットを含むメッセージ内のフィールドの名前。

COMMIT_ONLY

コミットが発生したことを示します。

CONTEXT_FIELD

バイト配列としてttApplicationContextプロシージャに渡されたコンテキスト値を含むメッセージ内のフィールドの名前。

CREATE_INDEX

索引が作成されたことを示します。

CREATE_SEQ

順序が作成されたことを示します。

CREATE_SYNONYM

シノニムが作成されたことを示します。

CREATE_TABLE

表が作成されたことを示します。

CREATE_VIEW

ビューが作成されたことを示します。

DELETE

行が削除されたことを示します。

DROP_COLUMNS

列が削除されたことを示します。

DROP_INDEX

索引が削除されたことを示します。

DROP_SEQ

順序が削除されたことを示します。

DROP_SYNONYM

シノニムが削除されたことを示します。

DROP_TABLE

表が削除されたことを示します。

DROP_VIEW

ビューが削除されたことを示します。

FIRST_FIELD

トランザクションの最初のレコードを示すフラグを含むフィールドの名前。

INSERT

行が挿入されたことを示します。

MTYP_FIELD

タイプ情報を含むメッセージ内のフィールドの名前。

MVER_FIELD

XLAレコードのトランザクション・ログ・ファイル数を含むメッセージ内のフィールドの名前。

NULLS_FIELD

NULL値を持つフィールドのリストを含むメッセージ内のフィールドの名前。

REPL_FIELD

レプリケーションで更新が適用されたことを示すフラグを含むメッセージ内のフィールドの名前。

TBLNAME_FIELD

表の名前を含むメッセージ内のフィールドの名前。

TBLOWNER_FIELD

表の所有者を指定するメッセージ内のフィールドの名前。

TRUNCATE

表が切り捨てられたことを示します。

TYPE_FIELD

メッセージ・タイプを指定するメッセージ内のフィールドの名前。

UPDATE

行が更新されたことを示します。

UPDATE_DESCRIPTOR_FIELD

バイト配列としてttXlaUpdateDesc_tを返すフィールドの名前。

UPDATED_COLUMNS_FIELD

更新された列のリストを含むメッセージ内のフィールドの名前。

XLAフラグ

すべての更新タイプに対して、MapMessageには次のことを示す名前と値のペアが含まれています。

- トランザクションの最初のレコードであるかどうか

- トランザクションの最後のレコードであるかどうか

- 更新がレプリケーションによって実行されたかどうか

- どの表が更新されたか

- 更新された表の所有者

表6-2に、これらのXLAフラグを含む名前と値のペアを示します。各名前の先頭には、2つのアンダースコアが付いています。

表6-2 JMS/XLAフラグ

名前

説明

対応するttXlaUpdateDesc_tフラグ

__AGING_DELETE

エージングによって削除されたことを示します。このフラグは、XLA更新レコードがエージングによって削除された場合のみ示されます。XlaConstants定数AGING_DELETE_FIELDがこのフラグを表します。

TT_AGING

__CASCADING_DELETE

カスケード削除によって削除されたことを示します。このフラグは、XLA更新レコードがカスケード削除によって削除された場合のみ示されます。XlaConstants定数CASCADING_DELETE_FIELDがこのフラグを表します。

TT_CASCDEL

__COMMIT

トランザクション内の最終レコードであり、この操作の後にコミットが実行されたことを示します。これは、TT_UPDCOMMITがオンの場合にMapMessageに含まれます。XlaConstants定数COMMIT_FIELDがこのフラグを表します。

TT_UPDCOMMIT

__FIRST

新規トランザクション内の最初のレコードであることを示します。これは、TT_UPDFIRSTがオンの場合にMapMessageに含まれます。XlaConstants定数FIRST_FIELDがこのフラグを表します。

TT_UPDFIRST

__REPL

この変更がレプリケーションによってデータベースに適用されたことを示します。これは、TT_UPDREPLがオンの場合にMapMessageに含まれます。XlaConstants定数REPL_FIELDがこのフラグを表します。

TT_UPDREPL

__UPDCOLS

これは、XLA更新ディスクリプタにはその操作によって実際に変更された列のリストが含まれることを示すUPDATETUPレコードのみに使用されます。これは、列名のリストがセミコロンで区切られた文字列として指定され、TT_UPDCOLSがオンの場合にのみMapMessageに含まれます。XlaConstants定数UPDATE_COLUMNS_FIELDがこのフラグを表します。

TT_UPDCOLS

注意:
XlaConstantsインタフェースは、com.timesten.dataserver.jmsxlaパッケージ内にあります。

アプリケーションは、MapMessageメソッドitemExists()を使用して、フラグが示されるかどうか判断したり、getBoolean()を使用して、フラグが設定されているかどうかを判断できます。入力時に、XlaConstants.AGING_DELETE_FIELDなどのフラグに対応するXlaConstants定数を指定します。

例6-1 コミットの確認

XLAでTT_UPDCOMMITを使用するのと同じように、JMS/XLAで、これがトランザクションの最後のレコードであるか、操作後にコミットが実行されたかを確認するため次のテストを行うことができます。

if (MapMessage.getBoolean(XlaConstants.COMMIT_FIELD) ) { // Field is set
...
}

DMLイベント・データの書式

多くのDML操作は、XLAイベント・ハンドラで監視可能なXLA更新を生成します。この項では、これらの操作を行うために生成されるMapMessageオブジェクトの内容について説明します。

表データ

INSERT、UPDATEおよびDELETE操作では、MapMessageには、__TBLOWNERおよび__TBLNAMEという2つの名前と値のペアが含まれます。これらのフィールドには、更新される表の名前と所有者が記述されます。たとえば、表SCOTT.EMPLOYEESでは、すべての関連するMapMessageに、文字列SCOTTの値が入った__TBLOWNERというフィールドと、文字列EMPLOYEESの値が入った__TBLNAMEというフィールドが含まれます。

行データ

INSERTおよびDELETE操作では、挿入または削除された行の完全なイメージはメッセージに含まれ、すべての列値を使用できます。

UPDATE操作の場合、実際に変更された列を示す列番号のリストだけでなく、行の前後のイメージが使用可能です。列値には、列の名前を使用してアクセスします。前のイメージの列名は、すべて1つのアンダースコアで始まります。たとえば、columnnameには新規の値が含まれており、_columnnameには以前の値が含まれています。

列の値がNULLである場合、列の値は列リストから省略されます。__NULLSの名前と値のペアには、NULL値を含む列のセミコロンで区切られたリストが含まれています。

コンテキスト情報

ttApplicationContext組込みプロシージャを使用してXLAレコード内のコンテキスト情報がエンコードされた場合、その情報はMapMessageの__CONTEXT名前と値のペアに含まれます。コンテキスト情報が提供されていない場合、__CONTEXT値はMapMessageには含まれません。

DDLイベント・データの書式

多くのデータ定義言語(DDL)操作は、XLAイベント・ハンドラで監視可能なXLA更新を生成します。この項では、これらの操作を行うために生成されるMapMessageオブジェクトの内容について説明します。

CREATE_TABLE

__TYPE=1(XlaConstants.CREATE_TABLE)が指定されているメッセージは、表が作成されていることを示します。表6-3に、CREATE_TABLE操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-3 更新メッセージで提供されるCREATE_TABLEデータ

名前

値

OWNER

作成された表の所有者の文字列値

NAME

作成された表の名前の文字列値

PK_COLUMNS

この表の主キー内の列の名前を含む文字列値

表に主キーがない場合、PK_COLUMNS値は指定されません。

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

COLUMNS

表の列の名前を含む文字列値

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

注意: 表の列ごとに、列について説明する追加の名前と値のペアがMapMessageに含まれています。

_column_name_TYPE

この列の(java.sql.Typesからの)データ型を表す整数値

_column_name_PRECISION

この列の精度を含む整数値(NUMERICまたはDECIMAL)

_column_name_SCALE

この列のスケールを含む整数値(NUMERICまたはDECIMAL)

_column_name_SIZE

この列の最大サイズを示す整数値(CHAR、VARCHAR、BINARYまたはVARBINARY)

_column_name_NULLABLE

この列でNULL値が許可されているかどうかを示すブール値

_column_name_OUTOFLINE

この列がタプルのインラインまたはアウトラインのいずれに保存されるかを示すブール値

_column_name_INPRIMARYKEY

この列が表の主キーの一部であるかどうかを示すブール値

DROP_TABLE

__TYPE=2 (XlaConstants.DROP_TABLE)が指定されているメッセージは、表が削除されていることを示します。表6-4に、DROP_TABLE操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-4 更新メッセージで提供されるDROP_TABLEデータ

名前

値

OWNER

順序の所有者の文字列値

NAME

削除された順序の名前の文字列値

CREATE_INDEX

__TYPE=3(XlaConstants.CREATE_INDEX)が指定されているメッセージは、索引が作成されていることを示します。表6-5に、CREATE_INDEX操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-5 更新メッセージで提供されるCREATE_INDEXデータ

名前

値

TBLOWNER

索引が作成された表の所有者の文字列値

TBLNAME

索引が作成された表の名前の文字列値

IXNAME

作成された索引の名前の文字列値

INDEX_TYPE

P(主キー)、F(外部キー)、R(標準)の索引タイプを表す文字列値

INDEX_METHOD

H(ハッシュ)、T(範囲)、B(ビットマップ)の索引メソッドを表す文字列値

UNIQUE

索引が一意であるかどうかを示すブール値

HASH_PAGES

ハッシュ索引内のページ数を表す整数値(範囲索引には指定されません)

COLUMNS

索引内の列について説明する文字列値

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

DROP_INDEX

__TYPE=4(XlaConstants.DROP_INDEX)が指定されているメッセージは、索引が削除されていることを示します。表6-6に、DROP_INDEX操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-6 更新メッセージで提供されるDROP_INDEXデータ

名前

値

OWNER

索引が削除された表の所有者の文字列値

TABLE_NAME

索引が削除された表の名前の文字列値

INDEX_NAME

削除された索引の名前の文字列値

ADD_COLUMNS

__TYPE=5(XlaConstants.ADD_COLUMNS)が指定されているメッセージは、表に新規列が追加されていることを示します。表6-7に、ADD_COLUMNS操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-7 更新メッセージで提供されるADD_COLUMNSデータ

名前

値

OWNER

変更された表の所有者の文字列値

NAME

変更された表の名前の文字列値

PK_COLUMNS

この表の主キー内の列の名前を含む文字列値

表に主キーがない場合、PK_COLUMNS値は指定されません。

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

COLUMNS

表に追加された列の名前を含む文字列値

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

注意: 追加する列ごとに、列について説明する追加の名前と値のペアがMapMessageに含まれています。

_column_name_TYPE

この列の(java.sql.Typesからの)データ型を表す整数値

_column_name_PRECISION

この列の精度を含む整数値(NUMERICまたはDECIMAL)

_column_name_SCALE

この列のスケールを含む整数値(NUMERICまたはDECIMAL)

_column_name_SIZE

この列の最大サイズを示す整数値(CHAR、VARCHAR、BINARYまたはVARBINARY)

_column_name_NULLABLE

この列でNULL値が許可されているかどうかを示すブール値

_column_name_OUTOFLINE

この列がタプルのインラインまたはアウトラインのいずれに保存されるかを示すブール値

_column_name_INPRIMARYKEY

この列が表の主キーの一部であるかどうかを示すブール値

DROP_COLUMNS

__TYPE=6(XlaConstants.DROP_COLUMNS)が指定されているメッセージは、表から既存の列が削除されていることを示します。表6-8に、DROP_COLUMNS操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-8 更新メッセージで提供されるDROP_COLUMNSデータ

名前

値

OWNER

変更された表の所有者の文字列値

NAME

変更された表の名前の文字列値

COLUMNS

表から削除された列の名前を含む文字列値

書式:

<col1name>[;<col2name> [;<col3name>[;...]]]

注意: 削除された列ごとに、列について説明する追加の名前と値のペアがMapMessageに含まれています。

_column_name_TYPE

この列の(java.sql.Typesからの)データ型を表す整数値

_column_name_PRECISION

この列の精度を含む整数値(NUMERICまたはDECIMAL)

_column_name_SCALE

この列のスケールを含む整数値(NUMERICまたはDECIMAL)

_column_name_SIZE

この列の最大サイズを示す整数値(CHAR、VARCHAR、BINARYまたはVARBINARY)

_column_name_NULLABLE

この列でNULL値が許可されているかどうかを示すブール値

_column_name_OUTOFLINE

この列がタプルのインラインまたはアウトラインのいずれに保存されるかを示すブール値

_column_name_INPRIMARYKEY

この列が表の主キーの一部であるかどうかを示すブール値

CREATE_VIEW

__TYPE=14(XlaConstants.CREATE_VIEW)が指定されているメッセージは、マテリアライズド・ビューが作成されていることを示します。表6-9に、CREATE_VIEW操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-9 更新メッセージで提供されるCREATE_VIEWデータ

名前

値

OWNER

作成されたビューの所有者の文字列値

NAME

作成されたビューの名前の文字列値

DROP_VIEW

__TYPE=15(XlaConstants.DROP_VIEW)が指定されているメッセージは、マテリアライズド・ビューが削除されていることを示します。表6-10に、DROP_VIEW操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-10 更新メッセージで提供されるDROP_VIEWデータ

名前

値

OWNER

削除されたビューの所有者の文字列値

NAME

削除されたビューの名前の文字列値

CREATE_SEQ

__TYPE=16(XlaConstants.CREATE_SEQ)が指定されているメッセージは、順序が作成されていることを示します。表6-11に、CREATE_SEQ操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-11 更新メッセージで提供されるCREATE_SEQデータ

名前

値

OWNER

作成された順序の所有者の文字列値

NAME

作成された順序の名前の文字列値

CYCLE

CYCLEオプションが新規の順序に指定されているかどうかを示すブール値

INCREMENT

INCREMENT BYオプションが新規の順序に指定されていることを示すlong値

MIN_VALUE

MINVALUEオプションが新規の順序に指定されていることを示すlong値

MAX_VALUE

MAXVALUEオプションが新規の順序に指定されていることを示すlong値

DROP_SEQ

__TYPE=17(XlaConstants.DROP_SEQ)が指定されているメッセージは、順序が削除されていることを示します。表6-12に、DROP_SEQ操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-12 更新メッセージで提供されるDROP_SEQデータ

名前

値

OWNER

削除された表の所有者の文字列値

NAME

削除された表の名前の文字列値

CREATE_SYNONYM

__TYPE=19(XlaConstants.CREATE_SYNONYM)が指定されているメッセージは、シノニムが作成されていることを示します。表6-13に、CREATE_SYNONYM操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-13 更新メッセージで提供されるCREATE_SYNONYMデータ

名前

値

OWNER

作成されたシノニムの所有者の文字列値

NAME

作成されたシノニムの名前の文字列値

OBJECT_OWNER

シノニムを作成するオブジェクトのスキーマの文字列値

OBJECT_NAME

シノニムを作成するオブジェクトの名前の文字列値

IS_PUBLIC

シノニムがパブリックであるかどうかを示すブール値

IS_REPLACE

シノニムがCREATE OR REPLACEを使用して作成されたかどうかを示すブール値

DROP_SYNONYM

__TYPE=20(XlaConstants.DROP_SYNONYM)が指定されているメッセージは、シノニムが削除されていることを示します。表6-14に、DROP_SYNONYM操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-14 更新メッセージで提供されるDROP_SYNONYMデータ

名前

値

OWNER

削除されたシノニムの所有者の文字列値

NAME

削除されたシノニムの名前の文字列値

IS_PUBLIC

シノニムがパブリックであったかどうかを示すブール値

TRUNCATE

__TYPE=18(XlaConstants.TRUNCATE)が指定されているメッセージは、表が切り捨てられていることを示します。表内のすべての行が削除されています。表6-15に、TRUNCATE操作に対して生成されるMapMessageに含まれている名前と値のペアを示します。

表6-15 更新メッセージで提供されるTRUNCATEデータ

名前

値

OWNER

切り捨てられた表の所有者の文字列値

NAME

切り捨てられた表の名前の文字列値

データ型のサポート

この項では、JMS/XLAに対するデータ型の考慮事項を説明します。

データ型のマッピング

表6-16に、TimesTenでサポートされているデータ型に対するアクセス方法を示します。データ型の詳細は、『Oracle TimesTen In-Memory Database SQLリファレンス・ガイド』のデータ型に関する項を参照してください。

表6-16 データ型のマッピング

TimesTenの列のデータ型

MapMessageメソッドでの読取り

CHAR(n)

getString()

VARCHAR(n)

getString()

NCHAR(n)

getString()

NVARCHAR(n)

getString()

NVARCHAR2(n)

getString()

DOUBLE

getString()

アプリケーションでBigDecimalまたはDoubleに変換可能。

FLOAT

getString()

アプリケーションでBigDecimalまたはDoubleに変換可能。

DECIMAL(p,s)

getString()

アプリケーションでBigDecimalまたはDoubleに変換可能。

NUMERIC(p,s)

getString()

アプリケーションでBigDecimalまたはDoubleに変換可能。

INTEGER

getInt()

SMALLINT

getShort()

TINYINT

getShort()

BINARY(n)

getBytes()

VARBINARY(n)

getBytes()

DATE

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。

アプリケーションでDateまたはCalendarに変換可能。

TIME

getString()

アプリケーションでDateまたはCalendarに変換可能。

TIMESTAMP

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。ナノ秒は切り捨てられます。ナノ秒の精度が必要な場合は、getString()を使用します。

アプリケーションでDateまたはCalendarに変換可能。

TT_CHAR

getString()

TT_VARCHAR

getString()

TT_NCHAR

getString()

TT_NVARCHAR

getString()

ORA_CHAR

getString()

ORA_VARCHAR2

getString()

ORA_NCHAR

getString()

ORA_NVARCHAR2

getString()

VARCHAR2

getString()

TT_TINYINT

getShort()

TT_SMALLINT

getShort()

TT_INTEGER

getInt()

TT_BIGINT

getLong()

BINARY_FLOAT

getFloat()

BINARY_DOUBLE

getDouble()

REAL

getFloat()

NUMBER

getString()

ORA_NUMBER

getString()

TT_DECIMAL

getString()

TT_TIME

getString()

TT_DATE

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。

TT_TIMESTAMP

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。

ORA_DATE

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。

ORA_TIMESTAMP

getLong()、getString()

getLong()メソッドは、起点(1970年1月1日、00:00:00 UTC)からのマイクロ秒を戻します。ナノ秒は切り捨てられます。ナノ秒の精度が必要な場合は、getString()を使用します。

TT_BINARY

getBytes()

TT_VARBINARY

getBytes()

ROWID

getBytes()、getString()

BLOB

getBytes()

注意: LOB自体の情報は得られません。LOBフィールドには長さがゼロのデータまたはnullデータが含まれます(値が実際にNULLの場合)。

CLOB、NCLOB

getString()

注意: LOB自体の情報は得られません。LOBフィールドには長さがゼロのデータまたはnullデータが含まれます(値が実際にNULLの場合)。

データ型キャラクタ・セット

JMS/XLAでは、次のデータ型にUTF-16キャラクタ・セットを使用します。

- TT_CHAR

- TT_VARCHAR

- ORA_CHAR

- ORA_VARCHAR2

- TT_NCHAR

- TT_NVARCHAR

- ORA_NCHAR

- ORA_NVARCHAR2

- NCHAR

- NVARCHAR

- NVARCHAR2

イベント処理用のJMSクラス

次のJMSクラスは、JMS/XLAアプリケーションで使用できます。JMS/XLA APIではパブリッシュ/サブスクライブ・メッセージのみがサポートされていることに注意してください。

- Message(親クラスのみ)

- TopicConnectionFactory

- トピック

- TopicSubscriber

- Connection

- Session

- ConnectionMetaData

- MapMessage

- TopicConnection

- TopicSession

- ConnectionFactory

- Destination

- MessageConsumer

- ExceptionListener

これらのクラスのマニュアルについては、次のJava EEの場所を参照してください(1つ目はJava 6用、2つ目はJava 5.0用)。

http://docs.oracle.com/javaee/6/api/
http://docs.oracle.com/javaee/5/api/

JMS/XLAレプリケーションAPI

TimesTen com.timesten.dataserver.jmsxlaパッケージには、TargetDataStoreインタフェースとTargetDataStoreImplクラスが含まれています。

詳細は、『Oracle TimesTen In-Memory Database JMS/XLA Java API Reference』を参照してください。

TargetDataStoreインタフェース

このインタフェースは、ソース・データベースからターゲット・データベースにXLA更新レコードを適用するために使用されます。ソースおよびターゲット・データベース・スキーマは、影響を受けた表で同一である必要があります。

このインタフェースは、表6-17に示すメソッドを定義します。

表6-17 TargetDataStoreメソッド

メソッド

説明

apply()

XLA更新記述子をターゲット・データベースに適用します。

close()

データベースへの接続をクローズし、リソースを解放します。

commit()

手動コミットを実行します。

getAutoCommitFlag()

自動コミット・フラグの値を返します。

getConnectString()

データベース接続文字列を返します。

getUpdateConflictCheckFlag()

更新の競合を確認するためのフラグの値を返します。

isClosed()

オブジェクトがクローズしているかどうかを確認します。

isDataStoreValid()

データベースが有効であるかを確認します。

rollback()

最後のトランザクションをロールバックします。

setAutoCommitFlag()

適用時に自動コミットのフラグを設定します。

setUpdateConflictCheckFlag()

適用時の更新の競合の確認のフラグを設定します。

TargetDataStoreImplクラス

このクラスは、ターゲット・データベースの接続とXLAハンドラを作成します。これは、TargetDataStoreインタフェースを実装します。

JMSのメッセージ・ヘッダー・フィールド

表6-18に、JMS/XLAで提供されているJMSのメッセージ・ヘッダー・フィールドを示します。

表6-18 JMS/XLAのヘッダー・フィールド

ヘッダー

内容

JMSMessageId

XLAレコードのトランザクション・ログ・ファイル数

JMSType

__TYPEフィールドの文字列表示

索引
A B C D E F G H I J L M N O P Q R S T U V W X

A

アクセス制御

接続属性, 2.2.1

接続, 2.2.6

JMS/XLAへの影響, 3.1.7

影響の概要, 2.5

応答, JMS/XLA, 3.1.6 ADD_COLUMNS, JMS/XLA, 6.3.5 配列バインド--「連想配列バインド」を参照 連想配列バインド, 2.3.4.5 非同期検出, 自動クライアント・フェイルオーバー, 2.7.4 非同期更新, JMS/XLA, 3.5 自動コミット・モード, 2.3.9.1 自動クライアント・フェイルオーバー

非同期検出, 2.7.4

構成, 2.7.2

概要, 機能, 2.7.1

同期検出, 2.7.3

B

SQL文のバッチ, 5.1.2

バインド変数--「バインド・パラメータ」を参照

パラメータのバインド

連想配列, 2.3.4.5

PL/SQLの重複したパラメータ, 2.3.4.4

SQLの重複したパラメータ, 2.3.4.3

バインド方法, 2.3.4.1

出力および入力/出力, 2.3.4.2

Blobインタフェースのサポート, 2.1.2 ブックマーク--「XLAブックマーク」を参照 組込みプロシージャ

TimesTen組込みプロシージャのコール, 2.4.1

ttApplicationContext, 6.1.1

ttCkpt, 2.4.1

ttDataStoreStatus, 2.4.1

ttDurableCommit, 4.2.1

ttXlaBookMarkCreate, 3.5

ttXlaBookmarkDelete, 3.6.2

ttXlaSubscribe, 3.4

ttXlaUnsubscribe, 3.6.3

バルク・フェッチ行, 5.1.3 バルク挿入、更新、削除(バッチ), 5.1.2

C

キャッシュ

自動リフレッシュ・キャッシュ・グループとXLA, 3.1.8

キャッシュ・グループ, 影響を受けたキャッシュ・インスタンス, 2.4.3.2

Oracleパスワード, 2.4.3

パススルー・レベルの設定, 2.4.3.1

CALL

PL/SQLプロシージャおよびファンクション, 2.4.1

TimesTen組込みプロシージャ, 2.4.1

CallableStatementインタフェース・サポート, 2.1.2 cancel文, 2.1.2 エラーの検出, 2.6.3 データ型のキャラクタセット, JMS/XLA, 6.4.2 クライアント・フェイルオーバー--「自動クライアント・フェイルオーバー」を参照 ClientFailoverEventクラス, TimesTen, 2.1.6 ClientFailoverEventListenerインタフェース, TimesTen, 2.1.6 Clobインタフェースのサポート, 2.1.2 コミット

自動コミット・モード, 2.3.9.1

commit()メソッド, 2.3.9.2

変更のコミット, 2.3.9

手動コミット, 2.3.9.2

SQL COMMIT文, 2.3.9.3

構成ファイル, JMS/XLA, 3.1.4 接続

接続URL, 作成, 2.2.1

直接接続のオープンおよびクローズ, 2.2.4

TimesTenXADataSource, JTA, 4.3.2

TimesTenへ, 2.2

XLAへ, 3.3

ユーザー名とパスワード, 2.2.2

XAConnection, JTA, 4.3.2

XAResourceおよびConnection, JTA, 4.3.3

接続属性

最初の接続属性, 2.2.1

一般接続属性, 2.2.1

プログラムでの設定, 2.2.1

接続イベント, ConnectionEventのサポート, 2.1.4 Connectionインタフェース・サポート, 2.1.2 接続プール, 2.1.4 ConnectionPoolDataSourceインタフェース・サポート, 2.1.4 CREATE_INDEX, JMS/XLA, 6.3.3 CREATE_SEQ, JMS/XLA, 6.3.9 CREATE_SYNONYM, JMS/XLA, 6.3.11 CREATE_TABLE, JMS/XLA, 6.3.1 CREATE_VIEW, JMS/XLA, 6.3.7 カーソル

コミットのクローズ, 2.3.9

REF CURSOR, 2.3.5

結果セットのヒントおよび制限, 2.3.2

D

データソース, JTA, 4.3.2

データ型

キャラクタ・セット, JMS/XLA, 6.4.2

変換およびパフォーマンス, 5.1.5

マッピング, JMS/XLA, 6.4.1

DatabaseMetaDataインタフェース・サポート, 2.1.2 DataSourceインタフェース・サポート, 2.1.4 デモ・アプリケーション, クイックスタート, 1.4 直接接続, オープンおよびクローズ, 2.2.4 切断, TimesTenから, 2.2.3 分散トランザクション処理--「JTA」を参照 DML RETURNING, 2.3.6 ドライバ(JDBC), ロード(Java 5), 2.2 DriverManagerクラス, 使用, 2.2.4 DROP_COLUMNS, JMS/XLA, 6.3.6 DROP_INDEX, JMS/XLA, 6.3.4 DROP_SEQ, JMS/XLA, 6.3.10 DROP_SYNONYM, JMS/XLA, 6.3.12 DROP_TABLE, JMS/XLA, 6.3.2 DROP_VIEW, JMS/XLA, 6.3.8 表のドロップ, JMS/XLA, 要件, 3.6.3 DuplicateBindMode一般的な接続属性, 2.3.4.3 永続コミット, JTA, 4.2.1

E

環境変数, 1.2

エラー

エラーの検出および対応, 2.6.3

エラーのレベル, 2.6.1

致命的エラー, 2.6.1.1

処理, 2.6

致命的ではないエラー, 2.6.1.2

レポート, 2.6.2

失敗したトランザクションのロールバック, 2.6.4

警告, 2.6.1.3

XA/JTAエラー処理, 4.2.3

SQLファンクションのエスケープ構文, 2.3.11 イベント・データの書式, JMS/XLA

DDLイベント, 6.3

DMLイベント, 6.2

イベント処理, JMSクラス, 6.5 例外--「エラー」を参照 SQL文の実行, 2.3.1, 2.3.4.1 拡張, JDBC, TimesTenによるサポート, 2.1.5

F

フェイルオーバー--「自動クライアント・フェイルオーバー」を参照

致命的エラー, 処理, 2.6.1.1

フェッチ

複数の行, 2.3.3

結果, 単純な例, 2.3.1

最初の接続属性, 2.2.1 フラグ, XLA, 6.1.2

G

GDK, JMS/XLAの依存性, JMS/XLA, 3.2

一般接続属性, 2.2.1

getString()メソッド, パフォーマンス, 5.1.4

グローバル・トランザクション, リカバリ, JTA, 4.2.2

グローバリゼーション, GDKの依存性, JMS/XLA, 3.2

H

ヘッダー・フィールド, メッセージ, JMS/XLA, 6.7

I

入力/出力パラメータ, 2.3.4.2

TimesTenおよびJDKのインストール, 1.1

Instant Client, 1.2

isDataStoreValid()メソッド, 2.2.5

J

Java 5およびJava 6用のJARファイル, 1.3

Java 5 JARファイル, 1.3

Java 6

JARファイル, 1.3

RowIdインタフェースのサポート, 2.1.2, 2.3.7

ROWID型, 2.3.7

Java環境変数, 1.2 JavaトランザクションAPI--「JTA」を参照 java.sql

サポートされているクラス, 2.1.3

サポートされているインタフェース, 2.1.2

javax.sql, サポートされるインタフェースとクラス, 2.1.4 JDBCドライバ, ロード(Java 5), 2.2 JDBCサポート

追加のTimesTenインタフェースおよびクラス, 2.1.6

java.sqlのサポートされているクラス, 2.1.3

java.sqlのサポートされているインタフェース, 2.1.2

キー・クラスおよびインタフェース, 2.1

パッケージのインポート, 2.1.1

TimesTenの拡張, 2.1.5

JDK, インストール, 1.1 JMS/XLA

アクセス制御の影響, 3.1.7

非同期更新, 3.5

ブックマーク--「XLAブックマーク」を参照

データ型のキャラクタセット, 6.4.2

接続のクローズ, 3.6.1

概念, 3.1

構成ファイル, 3.1.4

XLAへの接続, 3.3

データ型のマッピング, 6.4.1

表の削除, 3.6.3

イベント・データの書式, DDL, 6.3

イベント・データの書式, DML, 6.2

イベント処理, JMSクラス, 6.5

フラグ, 6.1.2

GDKの依存性, 3.2

高いイベント率, 5.2.3

LOBサポート, 3.4, 3.5

MapMessageの内容, 6.1

MapMessageオブジェクト, XLA更新, 3.1.5

マテリアライズド・ビューおよびXLA, 3.1.2

メッセージ・ヘッダー・フィールド, 6.7

表の監視, 3.4

パフォーマンス・チューニング, 5.2

更新の受信および処理, 3.5

レプリケーションAPI, 6.6

JMS/XLAを使用したレプリケーション, 3.7

同期更新, 3.5

表のサブスクリプション, 検証, 3.4

JMS/XLAアプリケーションの終了, 3.6

トピック, 3.1.4

表からのサブスクライブ解除, 3.6.3

更新タイプ, 6.1.1

XLA応答およびパフォーマンス, 5.2.2

XLA応答, 3.1.6

XLAの更新, 3.1.5

JTA

API, 4.3

永続コミット, 4.2.1

エラー処理, XA, 4.2.3

グローバル・トランザクション, リカバリ, 4.2.2

概要, 4.1

パッケージ, 要求, 4.3.1

要件, データベース, 4.2.1

リソース・マネージャ, 4.1.1

TimesTenXADataSource, 4.3.2

トランザクション・マネージャ, 4.1.1

2フェーズ・コミット, 4.1.2

XAConnection, 4.3.2

XAResource, 4.3.3

X/Open DTPモデル, 4.1.1

L

JDBCドライバのロード(Java 5), 2.2

LOB

JDBC, 2.3.8

JMS/XLAサポート, 3.4, 3.5

概要, 2.3.8

M

MapMessage

内容, 6.1

Map Messageオブジェクト, XLA更新, 3.1.5

マテリアライズド・ビューおよびXLA, 3.1.2 メッセージ・ヘッダー・フィールド, JMS/XLA, 6.7 表の監視, JMS/XLA, 3.4 マルチスレッド環境, 2.3.10

N

NClobインタフェースのサポート, 2.1.2

O

ObservableConnection, 2.1.4

ObservableConnectionDS, 2.1.4

Oracle Globalization Development Kit, サポートされているバージョン, JMS/XLA, 3.2

Oracle Instant Client, 1.2

Oracleパスワード, キャッシュ用, 2.4.3

orai18n.jarバージョン, JMS/XLA, 3.2

出力パラメータ, 2.3.4.2

P

パッケージのインポート, JDBC, 2.1.1

パッケージ, 要求, JTA, 4.3.1

パラレル・レプリケーション, ユーザー定義, 設定およびJDBCサポート, 2.4.4

ParameterMetaDataインタフェース・サポート, 2.1.2

パラメータ

連想配列, 2.3.4.5

バインド, 2.3.4.1

PL/SQLの重複したパラメータ, 2.3.4.4

SQLの重複したパラメータ, 2.3.4.3

出力および入力/出力, 2.3.4.2

パススルー, ttOptSetFlagでのレベルの設定, 2.4.3.1 接続用のパスワード, 2.2.2 パフォーマンス

バッチの実行, 5.1.2

バルク・フェッチ行, 5.1.3

データ型の変換, 5.1.5

getString()メソッド, 5.1.4

高いイベント率, JMS/XLA, 5.2.3

JDBCアプリケーションのチューニング, 5.1

JMS/XLAアプリケーションのチューニング, 5.2

準備された文のプール, 5.1.1

XLAの応答, 5.2.2

PL/SQLのプロシージャとファンクション, コール, 2.4.1 プール済の接続, クライアント・フェイルオーバー, 2.7.1.2 PooledConnectionインタフェース・サポート, 2.1.4 準備された文のプール, 5.1.1 プリフェッチ

およびパフォーマンス, 5.2.1

複数行のフェッチ, 2.3.3

xlaPrefetchパラメータ, 5.2.1

準備済の文

プール, 5.1.1

共有, 2.3.4.1

PreparedStatementインタフェース・サポート, 2.1.2 SQL文の準備, 2.3.4.1, 2.3.4.1 権限--「アクセス制御」を参照

Q

問合せしきい値(またはいずれかのSQL), 2.4.2.2

問合せタイムアウト(またはいずれかのSQL), 2.4.2.1

問合せ, 実行, 2.3.1

デモ・アプリケーションおよびチュートリアルのクイックスタート, 1.4

R

リカバリ, グローバル・トランザクション, JTA, 4.2.2

REF CURSOR, 2.3.5

レプリケート済ブックマーク, JMS/XLA, 3.1.3.2

レプリケーション

JMS/XLAレプリケーションAPI, 6.6

JMS/XLAの使用, 3.7

リソース・マネージャ, JTA, 4.1.1 結果セット, ヒントおよび制限, 2.3.2 ResultSetインタフェース・サポート, 2.1.2 ResultSetMetaDataインタフェース・サポート, 2.1.2 RETURNING INTO句, 2.3.6 ロールバック

rollback()メソッド, 2.3.9.2

失敗したトランザクションのロールバック, 2.6.4

SQL ROLLBACK, 2.3.9.3

ROWID

RowIdインタフェースのサポート, 2.1.2, 2.3.7

rowidのサポート, 2.3.7

ROWID型, 2.3.7

S

セキュリティ--「アクセス制御」を参照

Statementインタフェース・サポート, 2.1.2

文

取消し, 2.1.2

実行, 2.3.1, 2.3.4.1

準備, 2.3.4.1, 2.3.4.1

サブスクリプション(JMS/XLA), 表, 検証, 3.4 同期検出, 自動クライアント・フェイルオーバー, 2.7.3 同期更新, JMS/XLA, 3.5

T

表のサブスクリプション(JMS/XLA), 検証, 3.4

ターゲット・データベース

メッセージの適用, 3.7.1

競合の確認, 3.7.1

作成, 3.7.1

手動コミット, 3.7.1

ロールバック, 3.7.1

TargetDataStoreインタフェース, JMS/XLA

エラー・リカバリ, 3.7.2

メソッド, 6.6.1

TargetDataStoreImplクラス, JMS/XLA, 6.6.2 JMS/XLAアプリケーションの終了, 3.6 スレッド, マルチスレッド環境, 2.3.10 SQL文のしきい値, 2.4.2.2 SQL文のタイムアウト, 2.4.2.1 TimesTen Cache, 「キャッシュ」を参照 TimesTenBlobインタフェース, 2.1.5 TimesTenCallableStatementインタフェース, 2.1.5, 2.1.5 TimesTenClobインタフェース, 2.1.5 TimesTenConnectionインタフェース, 2.1.5, 2.1.5 TimesTenPreparedStatementインタフェース, 2.1.5, 2.1.5 TimesTenStatementインタフェース, 2.1.5, 2.1.5 TimesTenTypesインタフェース, 2.1.6 TimesTenVendorCodeインタフェース, 2.1.6, 2.6.3 TimesTenXADataSource, JTA, 4.3.2 トピック, JMS/XLA, 3.1.4 トランザクション・マネージャ, JTA, 4.1.1 TRUNCATE, JMS/XLA, 6.3.13 ttApplicationContext組込みプロシージャ, 6.1.1 ttCkpt組込みプロシージャ, 2.4.1 ttDataStoreStatus組込みプロシージャ, 2.4.1 ttXlaBookmarkCreate組込みプロシージャ, 3.5 ttXlaBookmarkDelete組込みプロシージャ, 3.6.2 ttXlaSubscribe組込みプロシージャ, 3.4 ttXlaUnsubscribe組込みプロシージャ, 3.6.3 チューニング

JDBCアプリケーション(パフォーマンス), 5.1

JMS/XLAアプリケーション(パフォーマンス), 5.2

2フェーズ・コミット, JTA, 4.1.2

U

表からのサブスクライブ解除, JMS/XLA, 3.6.3

更新タイプ, XLA, 6.1.1

更新, 実行, 2.3.1

更新, 受信および処理, JMS/XLA, 3.5

接続用のURL, 2.2.1

接続用のユーザー名, 2.2.2

データ型のUTF-16キャラクタセット, JMS/XLA, 6.4.2

V

妥当性, データベース, 確認, 2.2.5

W

警告, 2.6.1.3

X

XAConnection, JTA, 4.3.2

XADataSourceインタフェース・サポート, 2.1.4

XAResourceおよびConnection, JTA, 4.3.3

XA--「JTA」を参照

XLAブックマーク

削除, 3.6.2

概要, 3.1.3

レプリケート済ブックマーク, 3.1.3.2

xlaPrefetchパラメータ, 5.2.1 XLA--「JMS/XLA」を参照 X/Open DTPモデル, 4.1.1

オラクル社の法律上の注意点について

コピーライトについて

Copyright © 1994-2015, Oracle and/or its affiliates.All rights reserved.

商標と登録商標について

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

制限付権利

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations.As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs.No other rights are granted to the U.S. Government.

危険な用途への使用について

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション（人的傷害を発生させる可能性があるアプリケーションを含む）への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性（redundancy）、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。オラクル社およびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

ドラフトのアルファ版およびベータ版ドキュメントについて

このドキュメントが試作版の場合:

このドキュメントは試作版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。オラクル社およびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。