ナビゲーションをスキップ

WebLogic Server FAQ 集

  前 次 前/次ボタンと目次ボタンとの区切り線 目次  

FAQ : WebLogic JDBC

コンフィグレーション

プログラミング - 全般

プログラミング - Oracle


Q. WebLogic Server に付属の PointBase DBMS は開発やプロダクションに使用できますか。

A. WebLogic Server 配布キットに含まれている PointBase Server は、WebLogic Server の評価のみを目的とした all-Java の DBMS 製品です。試用版のカスタム アプリケーションまたは WebLogic Server 付属のサンプル アプリケーションでしか使用できません。評価を目的としない開発やプロダクションで PointBase Server を使用するには、エンド ユーザが PointBase からライセンスを別途取得する必要があります。


Q. WebLogic JDBC 接続プールで JDBC Oracle Thin ドライバを使用している場合、Oracle Advanced Security による暗号化を有効にするにはどうしたらよいですか。

A. Oracle Advanced Security による暗号化は、Oracle が提供する JDBC ドライバの接続プロパティで使用できる機能に依存します。接続プロパティは、[プロパティ] 属性の WebLogic JDBC 接続プールで指定できます。この属性は、Administration Console の JDBC 接続プールの [コンフィグレーション|全般] タブで設定できます。WebLogic Server で接続プールのデータベース接続が作成されると、このプロパティが JDBC ドライバに渡されます。これにより、指定したプロパティで接続が作成されます。

たとえば、Oracle Advanced Security による暗号化を有効にするには、オプションを以下のように指定します。

Properties:  user=SCOTT
oracle.net.encryption_client=ACCEPTED
oracle.net.encryption_types_client=RC4_256
oracle.net.crypto_checksum_client=ACCEPTED
protocol=thin

注意 : Oracle Advanced Security による暗号化のプロパティの詳細については、Oracle のドキュメントを参照してください。上に挙げたプロパティは、説明のみを目的としています。

この結果、config.xml ファイルのエントリは次のようになります。

<JDBCConnectionPool
DriverName="oracle.jdbc.driver.OracleDriver"
Name="oraclePool"
Password="{3DES}1eNn7kYGZVw="
Properties="user=SCOTT;
oracle.net.encryption_client=ACCEPTED;
oracle.net.encryption_types_client=RC4_256;
oracle.net.crypto_checksum_client=ACCEPTED;
protocol=thin"
URL="jdbc:oracle:thin:@server:port:sid"
/>

注意 : 読みやすくするために改行が追加されています。


Q. どのような場合に、DataSource ではなく TxDataSource を使うべきですか。

A. Administration Console オンライン ヘルプの「データ ソースでグローバル トランザクションを有効化すべき場合」を参照してください。Administration Console で [グローバル トランザクションを受け付ける] を選択した場合は、config.xml ファイルで JDBCTxDataSource を作成します (デフォルト)。[グローバル トランザクションを受け付ける] チェック ボックスをオフにした場合は、config.xml ファイルで JDBCDataSource を作成します。


Q. all-java (Type 4) ドライバとネイティブ ドライバ (Type 2) ではどちらがよいですか。

A. Type 4 ドライバの長所は、Java コードの長所と同じ移植性と安全性です。Java コードは Java 仮想マシン内で実行されるため、プロセスをクラッシュさせることはありません。

Type 2 ネイティブ ドライバの長所はパフォーマンスでした。しかし、Java のパフォーマンスが急激に改善されたため、この点はかならずしも長所とはいえなくなっています。通常、JDBC ドライバのパフォーマンスは、使用する SQL コード、JDBC ドライバの実装など、さまざまな要因によって左右されます。


Q. 接続プールの初期サイズはどのように設定したらよいでしょうか。

A. プロダクション システムでは、初期サイズを最大サイズと同じ値に設定します。これにより、サーバの起動時に必要となる JDBC 接続がすべて作成されます。

このように設定する理由は、初期接続数が最大接続数よりも少ないと、サーバがロードされたときに追加の接続を作成しなければならないためです。サーバに大きな負荷がかかっているときは、オーバーヘッドを最小限に抑えて通常の処理のみを実行することが目標になります。つまり、追加のデータベース接続の作成によってサーバにさらなる負荷がかかるのを避ける必要があるわけです。パフォーマンスと安定性の両面から、起動時には接続プールがすべての接続を作成しているのが最適といえます。

開発時は、初期サイズを 1 のような小さな値に設定します。これにより、サーバの起動が速くなり、サポートしている同時接続数が少ないデータベースでも使用可能になります。


Q. 接続プールの最大サイズはどのように設定したらよいでしょうか。

A. プロダクション環境では、アプリケーションおよびシステムによって最適な最大プールサイズが異なります。まずは、最大プール サイズを実行スレッド数と同じ値に設定するとよいでしょう。これにより、各実行スレッドに JDBC 接続を 1 つずつ割り当てることができ、スレッドが別のスレッドで使用中の接続を待機している間にブロックされることはありません。

アプリケーションによっては、最大プール サイズが実行スレッド数より少なくても実行できます。通常、こうしたケースは、サーバに入る処理に JDBC 接続を必要としないものがあり、I/O タスクを実行するスレッドがたくさんある場合に発生します。

一部のアプリケーションは、最大プール サイズが実行スレッド数より大きくないと実行できません。通常、こうしたケースは同じ接続プールからの接続を複数必要とするスレッドがある場合に発生します。複数の接続を必要とするケースとしては、たとえば EJB メソッドがある接続を使用しており、そのトランザクションがコミットされる前に別の EJB で RequiresNew を呼び出す場合などが考えられます。この場合、RequiresNew EJB が専用の接続をプールから取得するためです。

理論的には、同時に処理するユーザと同数の接続が必要になります (ただし、これが現実的でなく、接続を連続して再利用しなければならない場合もあります)。

なお、これらの推奨設定では、接続リーク (予約したがクローズしていない接続) も考慮に入れてあります。

開発時には、最大サイズを小さな値に設定します。開発マシンに対して負荷テストを実行しないのであれば、同時ユーザの数が極端に多くなることは考えにくく、それほど多くの接続は必要ありません。また、接続プール内の接続が少なければ、アプリケーションが接続をクローズしないことが原因で、接続プールから接続がリークする可能性が高まります。開発時にこの問題が判明していれば、プロダクションに移行する前に修正できます。

接続がオブジェクトによって明示的に開放されない場合、その接続が接続プールに返されるのは、オブジェクトが破棄されたときか、接続が実際にクローズされたときになります。接続への参照がなくなると、その接続はガベージ コレクションの間に接続プールに返されます。ただし、接続へのリモート参照がある場合 (データ ソースを使用して接続を取得した場合) は、接続が返されなかったと感じるほどの遅延が発生します。これは、分散されたガベージ コレクションにはより時間がかかるためです。場合によっては、接続がプールに返されるまでに 6 分以上かかることもあります。

接続をガベージ コレクションによって接続プールに返すのは避けるようにしてください。使用済みの接続を接続プールに正しく返していないコードを突き止め、修正することをお勧めします。


Q. データベース接続用の JDBC 接続プールに対するリクエストを、接続が使用可能になるまで待機させることはできますか。

A. はい。次の 2 つの JDBC 接続プール プロパティを設定して、接続リクエストに接続を待機させることができます。

『WebLogic JDBC プログラマーズ ガイド』の「接続を待機する接続リクエストの有効化」を参照してください。


Q. 接続プールのデータベース接続に対して現在よりも多くのリクエストを送信する場合、どのようにすれば ResourceException を回避できますか。

A. 基本的な問題は、作業負荷に対してリソース (接続プール内のデータベース接続) が少なすぎることです。接続プール内の接続の最大数を増やすことが適切です。最適に設計されたアプリケーションの場合、サーバには、実行スレッドごとに 1 つのプール接続しか持たせていません。

接続リクエストに接続を待機させることもできます。『WebLogic JDBC プログラマーズ ガイド』の「接続を待機する接続リクエストの有効化」を参照してください。

リソース例外に対するアプリケーションの正しい対応は、緊密なループ内でリクエストを再試行しないことです。緊密なループ内でリクエストを再試行すると、実行スレッドがサーバに拘束されます。

使用可能な接続がない場合は正常に失敗するようにアプリケーションを設計してください。NoResource 例外が何度も発生しないように、アプリケーション コード内でできるだけ遅くに接続を取得し、できるだけ早く接続プールに返すようにしてください。次の例のように、接続をメソッド レベルの変数として持ち、finally ブロックで閉じるとよいでしょう。

try{ 
...
} catch(Exception handleEx) {
...
} finally {
try{ conn.close(); //常に接続をプールに返す
}catch (Exception ignore){}
}

Q. JDBC 接続は、いつ接続プールに返されますか。

A. アプリケーションが接続をどのように取得したかによって異なります。EJB などのアプリケーション コードでトランザクション データ ソース、JTS ドライバなどを使用し、WebLogic 管理のトランザクションの一部として接続を取得した場合は、コミット、ロールバック、またはタイムアウトによってトランザクションが終了すると同時に接続プールに返されます。

WebLogic 管理のトランザクションのコンテキストの外で、アプリケーション コードで非トランザクション データ ソースなどから接続を取得した場合は、アプリケーション コードが接続をクローズすると同時に接続プールに返されます。接続がクローズされると、最終的にはガベージ コレクションによって接続プールに返されます。ただし、この処理には時間がかかりいつ返されるかが不確定であるため、接続を必要とするアプリケーションでエラーが発生するおそれがあります。したがって、使い終わったプール接続はアプリケーションで確実にクローズすることが重要になります。また、JSP やサーブレットでは、1 つのクラスが複数のスレッドで同時に実行される場合があります。その場合、スレッドの 1 つが接続オブジェクトを新しいオブジェクトで上書きするおそれがあるため、接続オブジェクトをクラス変数やインスタンス変数でなくメソッド オブジェクトにしておくことが重要です。上書きされた接続はクローズできないため、ガベージ コレクションが実行されるまでは接続プール外で使用不可になってしまいます。


Q. データベースを再起動した場合やデータベースにアクセス不能になった場合は何が起こりますか。接続プールはそのまま使用できますか。

A. はい。プールは、DBMS と通信する機能からは独立しています。接続プール内のすべての接続は消滅するかもしれませんが、接続プールは引き続き存在します。接続プールをコンフィグレーションすることで、WebLogic Server がプール内の接続をテストし、可能であれば無効な接続を置き換えるようにすることができます。詳細については、『WebLogic JDBC プログラマーズ ガイド』の「接続プールおよびデータベース接続のテスト」を参照してください。

データベース障害の後に Administration Console を使用して手動で接続プールを再起動するには、すべてのデプロイメント対象を削除することで接続プールをアンデプロイしてから、デプロイメント対象を追加しなおすことで接続プールを再デプロイします。Administration Console オンライン ヘルプの「JDBC 接続プールの停止」を参照してください。

この作業を「weblogic.Admin」を使用してコマンドラインから行うには、接続プールの Targets 属性を空文字列 ("") に設定してから、必要なデプロイメント対象を設定しなおします。『WebLogic Server コマンド リファレンス』の「weblogic.Admin コマンドを使用したリソースの割り当て」を参照してください。


Q. コンソールに表示される「接続総数」とは何ですか。

A. 接続総数とは、そのプールが存在している間に作成された接続の累計数です。接続プール内に現存する接続の総数ではありません。接続は、接続プールが大きくなったとき、または無効な接続が置き換えられたときに追加されます。


Q. マルチプールはどのような場合に使用するのですか。

A. マルチプールは、2 つの方法で使用できます。1 つはデータベース接続が失敗した場合の高可用性を目的として使用する場合、もう 1 つはマルチプールをロード バランシングする目的で使用する場合です。どちらかの方法しか選択できないので、マルチプールの主な目的を決める必要があります。

注意 : JDBC アプリケーションのマルチプールを実装する場合は、そのマルチプールが使用する接続プールに対して、ドライバ レベルのロード バランシングまたはフェイルオーバをコンフィグレーションしないでください。マルチプールでは、ドライバ レベルのロード バランシングまたはフェイルオーバのコンフィグレーションと同様の機能を提供します。

詳細については、『WebLogic JDBC プログラマーズ ガイド』の「マルチプールのコンフィグレーションと使い方」を参照してください。


Q. マルチプールはクラスタ内でもサポートされていますか。

A. マルチプールは、クラスタ内でも基本の接続プールと同様にサポートされます。 アプリケーションが考慮されている限り、マルチプールと基本の接続プールを区別することはできません。接続プールを使用するアプリケーションがあり、これをクラスタのすべてのメンバーで実行する可能性がある場合は、クラスタの各メンバーの接続プールの名前を同じにする必要があります。これは、マルチプールにも適用されます。アプリケーションがマルチプールからの接続を必要とする場合は、クラスタの各メンバーのマルチプールを同じ名前にしておく必要があります。


Q. JTS はどのような場合に使用するのですか。

A. JTS を使用すると、グローバル トランザクションに関わるリソースとして、他の XA JDBC リソースとともに非 XA JDBC リソース (ドライバ) を使用できます。この XA エミュレーション モードをコンフィグレーションするには、非 XA JDBC ドライバを使用してデータベース接続を作成できるように JDBC 接続プールをコンフィグレーションしてから、トランザクション データ ソースの EnableTwoPhaseCommit 属性 (Administration Console では [非 XA ドライバ用に 2 フェーズ コミットをエミュレート]) を true に設定し、トランザクション データ ソースがこの JDBC 接続プールを指すようにコンフィグレーションします。このモードでは、データベースの更新がローカル データベース トランザクションを使用してコミットまたはロールバックされます。このモードでの処理は、以下の状況に適しています。

JTS を使用する際の制約は以下のとおりです。

このモードの詳細については、『Administration Console オンライン ヘルプ』の「2 フェーズ コミットのエミュレーション」を参照してください。


Q. データベースが利用可能かどうかは、どのように確認できますか。

A. 基本的には、接続を試してみる以外にデータベースがダウンしているかどうかを確認する方法はありません。

また、データベースは接続を行ったり、その接続を使用した後に使用できなくなることがあります。コードは、予期しないエラーが処理されるように記述することをお勧めします。エラーは、データベースがダウンしたときにクライアントが何をしているかによってさまざまなかたちで発生します。

WebLogic Server は、WebLogic Server と DBMS との間の JDBC ドライバを用いた接続をテストするためのユーティリティ dbping を提供しています。『WebLogic Server コマンド リファレンス』の「WebLogic Server Java ユーティリティの使い方」の「dbping」を参照してください。


Q. Microsoft for SQL Server 2000 のドライバをコンフィグレーションする方法を教えてください。

A. 『WebLogic JDBC プログラマーズ ガイド』の「Microsoft SQL Server 2000 Driver for JDBC のインストールと使い方」を参照してください。

MS SQL Server の各インスタンスは、異なるポートをリスンする必要があります。このため、getConnection() メソッドに渡すプロパティでポート番号を使用するか、接続プールの場合は、以下のプロパティにポートのプロパティを指定できます。

server=machine 
Nameport=instancePort

各 MS SQL Server インスタンスが実行されているポート番号を見つけるには、サーバ ネットワーク ユーティリティ (Microsoft SQL Server プログラム グループにある) を実行し、サーバ インスタンスを選択し、TCP/IP を選択して、プロパティ ボタンをクリックします。

msbase.jarmsutil.jar、および mssqlserver.jar ファイルの絶対パス名を、通常の CLASSPATH だけでなく、サーバ起動スクリプト (たとえば STARTWEBLOGIC.CMD) の CLASSPATH にも含める必要があります。

また、Administration Console で、接続プールの URL にセミコロン区切りで接続プロパティを追加する必要がある場合もあります ([プロパティ] フィールドは使用しません)。たとえば、次のように指定します。

jdbc:microsoft:sqlserver://127.0.0.1:1433;user=User;password=Password;databasename=DBName

注意 : Microsoft SQL Server データベースへの接続の作成には、WebLogic Type 4 JDBC Driver for Microsoft SQL Server を使用することをお勧めします。WebLogic Type 4 JDBC Driver for Microsoft SQL Server の詳細については、『WebLogic Type 4 JDBC ドライバ ガイド』を参照してください。


Q. XA 準拠のリソース マネージャに対し複数の更新を行うトランザクションの実行に長時間かかり、リソースの登録、準備、およびロールバック処理で XAException (errorCode=XAER_NOTA) が発生します。この現象の原因と回避策を教えてください。

A. Oracle など一部のリソース マネージャは内部タイムアウト メカニズムを備えており、タイムアウト期限が切れるとトランザクション ブランチに関係する処理を内部的にロールバックします。その後、WebLogic トランザクション マネージャがリソースに対して XAResource.start/prepare/rollback 処理を呼び出すと、指定した Xid がリソース マネージャ内に存在しないため、XAException XAER_NOTA が発生します。

javax.transaction.xa.XAResource インタフェースは、setTransactionTimeout というメソッドを提供します。このメソッドを使用すると、一部のドライバ実装でリソースの内部タイムアウト間隔を設定できます。WebLogic トランザクション マネージャは、各リソースの登録前のグローバル トランザクション タイムアウトと同じ値でこのメソッドを呼び出すように設定できます。JDBC 接続プールのコンフィグレーションでは、XASetTransactionTimeout 属性を true に設定してこの機能を有効にします。この JDBCConnectionPool 属性は、XA 準拠のドライバにのみ適用される点に注意してください。なお、この属性を設定しても、XAResource.setTransactionTimeout メソッドを実装していない XA ドライバには影響しません。

XASetTransactionTimeout 属性の詳細については、WebLogic Server の『リリース ノート』の「XAResource のトランザクション タイムアウトのサポート」を参照してください。

Oracle Thin ドライバは XAResource.setTransactionTimeout をサポートしています。WebLogic jDriver for Oracle ドライバはこのメソッドを実装していません。WebLogic jDriver for Oracle 使用時に Oracle セッション タイムアウトを設定するには、XA オープン文字列で SesTm を設定します。次に、config.xml ファイルの JDBCConnectionPool エントリ内にある XA オープン文字列の例を示します。

<:JDBCConnectionPool
DriverName= "weblogic.jdbc.oci.xa.XADataSource"
Name="XAPool"
Properties="user=system;password=manager;
openString=Oracle_XA+Acc=p/system/manager+SesTm=177+db=SUPPORT+Threads=true+Sqlnet=LINUX+logDir=.+dbgFl=0x15;dataSourceName=XAPool"
Targets="myserver" />

XAER_NOTA エラーは回復時にも発生します。この場合の XAER_NOTA エラーは、トランザクションがサーバの再起動より前にコミットされたにもかかわらず、サーバの起動時にもトランザクション ログに残っている場合に送出されます。回復処理中は、トランザクション ログ内のトランザクション記録ごとに、トランザクション マネージャがコミットの決定に関わっているリソースに通知します。リソースのコミット ディレクティブが再起動前に成功すると、リソース マネージャは Xid を認識できなくなるため、後続のコミットに対しては XAER_NOTA を送出します。トランザクション マネージャは、クラッシュ前にコミットが成功したものと判断してこのエラーを無視します。すでにコミットされたトランザクションがトランザクション ログの記録に残ってしまうのは、トランザクション マネージャがチェックポイント処理時にエントリのみを削除するためです。チェックポイントは、デフォルトでは 5 分ごとに発生し、すべての記録が開放されているトランザクション ログ ファイルを削除します。チェックポイントの間隔は、JTAMBean.CheckpointIntervalSeconds 属性でコンフィグレーションできます。Administration Console では、[ドメイン|コンフィグレーション|JTA] タブの [チェックポイント間隔の秒数] で設定できます。Administration Console オンライン ヘルプの「トランザクションのコンフィグレーション」を参照してください。


Q. ConnsOnReserve と refreshTestMinutes を一緒に使用するとどうなりますか。

A. これらはほぼ無関係です。予約時に接続をテストし、更新テスト オプションは使用しないことをお勧めします。アプリケーションが接続を必要とし、フリーな接続がすべて更新テストによってテストされている場合、更新テストが原因で一時的な例外が発生することがあります。更新テストを使用する価値があるのは、あまりに長い間アイドル状態にある接続がファイアウォールや DBMS によって切断される場合です。更新テストを使用すると、すべての接続が使用中であるかのように見せることができるからです。

接続テストの詳細については、Administration Console オンライン ヘルプの「JDBC 接続プールのテスト」を参照してください。


Q. Prepared Statement キャッシュはどのように使用するのですか。

A. Administration Console オンライン ヘルプの「Statement キャッシュによるパフォーマンス向上」を参照してください。

Prepared Statement キャッシュの使用に関するドキュメントは、http://www.theserverside.com/resources/article.jsp?l=Prepared-Statements でも入手できます。


Q. JDBC 接続を使用してプログラミングする上で気をつけるべきことはありますか。

A. 基本的なルールは、接続を接続プールから取得する際はできるだけ遅く、接続プールに返す際はできるだけ早くすることです。接続は必ずメソッド変数とし、それを使用する場所の同じメソッド内で接続を取得および開放するようにします (スレッドごとに専用の接続が必要です)。接続を取得するコストは小さく、準備時間は Prepared Statement キャッシュを使用することで短縮できます。SET 文のコストも大きくありません。実行は使用率に関係なく行う必要がありますが、クローズのコストもわずかです。ejbCreate/activate で接続を作成し、ejbRemove/pasivate でクローズすることをお勧めします。


Q. DriverManager.getConnection を使用すべきでないのはなぜですか。

A. DriverManager.getConnection はデッドロックの原因となります。サーバでは、すべてのドライバによる数多くの頻繁な呼び出しを含め、すべての DriverManager 呼び出しがクラス同期しており、JDBC ドライバはさまざまな同期を内部で実行しています。待機時間の長い呼び出しが 1 つあると、JVM 全体で JDBC のすべての処理が停止しデッドロックが発生します。また、ドライバを繰り返し登録しないよう注意してください。起動時に最初にロードしたドライバは、DBMS の状態に関係なく常に動作します。


Q. Prepared Statement を、複数のトランザクションをまたいで使用することはできますか。

A. はい。すべてのトランザクションは専用の JDBC 接続を使用し、すべてのデータベース対話は、トランザクションに参加するためにこの接続オブジェクトを使用する必要があります。したがって、Prepared Statement は特定の接続に関連付けられており、他の接続との間で共有することはできません。 しかし、Prepared Statement が複数のトランザクションをまたぐことは可能です。


Q. ドライバでメソッドを呼び出すと java.lang.AbstractMethodError が発生するのはなぜですか。

A. このエラーは、通常はドライバがそのメソッドを実装していないことを表します。たとえば、JDBC 2.0 メソッドしか実装していないドライバで JDBC 3.0 メソッドを呼び出すとこのエラーが発生します。


Q. 「ResourceException: No Resource Available」が発生するのはなぜですか。

A. 一般的な原因としては、接続プールにコンフィグレーションされた JDBC 接続の数、またはサーバ上の実行スレッドの数よりも、コンシューマ (接続ユーザ) の数が多すぎることが考えられます。

別の原因としては、更新テスト処理がテスト用に 1 つまたは複数の接続を予約しているため、これらの接続が一時的に使用できなくなっていることが考えられます。


Q. EJB のコンテナ管理トランザクションが開始されるたびに新しいデータベース接続が作成されている (したがって、そのたびに新しい認証/認可を取得している) ことを確認する方法はありますか。

A. EJB は必ずトランザクションを必要とします。これは、トランザクションがまだ進行中でなければ呼び出し時に開始し、進行中のトランザクションがあれば結合することを意味します。標準の JTS/JTA API を使用して UserTransaction を取得および開始するコードの場合、JDBC 接続をトランザクション データ ソースから取得する必要があり、これがトランザクションに含まれることになります。トランザクションを開始するたびに新しい接続を取得するには、動的プール API を使用して単一の接続プールを作成します。 サーバの起動時に単一の接続プールとトランザクション データ ソースが作成されるよう、サーバをコンフィグレーションしておくことをお勧めします。外部クライアントのトランザクションを実行する場合は、内部プールをいったん破棄してから、適切な DBMS ユーザで再作成します。これにより、トランザクション データ ソースを使用して接続を取得することが可能になり、UserTransaction を実行するコンテキストで取得した場合は、自動的にトランザクションに含まれます。


Q. JNDI 経由でデータ ソースをルックアップし、外部プロセスからデータベース接続にアクセスした場合、WebLogic プロセスの接続インスタンスのスタブを取得することになりますか。それとも、ローカル プロセスの別の接続で新しい接続プールを作成することになりますか。

A. WebLogic データ ソースであれば、ローカル プロセスの接続プールではなく、接続インスタンスのスタブを取得することになります。


Q. 分散トランザクションで JMS と JDBC を必要とする場合、JMS メッセージの処理時に JDBC の更新が使用可能であることを保証するにはどうしたらよいですか。

A. 問題は、関連する JDBC データがデータベースに更新される前に、アプリケーションが送り先から JMS メッセージを受信することができる点です。

分散トランザクションでは、関連するすべての変更が 1 つの単位として成功したか失敗したかを保証することはできますが、これらが同時に発生したかどうかを保証することはできません (トランザクション マネージャはすべてのリソース マネージャに対してコミットを指示しますが、その処理の完了タイミングを制御することはできません)。

WebLogic トランザクション マネージャの場合、JDBC 接続プールと JMS サーバが同じサーバに存在し、同じサーバでトランザクションを開始すると、トランザクションが要求した順序で変更がコミットされます。これはサポートされている動作ではありませんが、現状ではこのような動作になっています。したがって、JDBC 接続プールと JMS サーバを同じサーバに配置できるのであれば可能かもしれません。

JMS メッセージの発生時間を遅らせて送信し、この方法で問題ないか確認してください。

受信側が関連付けられた JDBC データを見つけることができなければ、メッセージをロールバックまたは回復できます。WebLogic JMS の再配信遅延機能を使用すれば、メッセージがただちに再配信されるのを防ぐことができます。


Q. アプリケーションが DataSource.getConnection を同じスレッドおよびトランザクションで複数回呼び出した場合、同じ接続およびトランザクションで処理されますか。

A. 1 つのトランザクション内 (開始/コミット) で複数のメソッドを呼び出すシナリオとしては、次のような処理が考えられます。

Context ctx = new InitialContext();
DataSource ds = (javax.sql.DataSource) ctx.lookup("connpoll");
// 接続を使用して処理

このケースであれば、データ ソース ds がトランザクション データ ソースである限り、すべての処理はトランザクションで行われ、同じ基底の JDBC 接続が使用されます。


Q. クライアントの XAResource を登録しようとすると SystemException が発生するのはなぜですか。

A. WebLogic Server では、クライアントの XA リソースを登録することはできません。この制約が設けられているのは、クライアントはサーバに比べて可用性の面で信頼性が低いと考えられるからです。クライアントがトランザクション コーディネータや同期化オブジェクトとして動作できないのも、これと同じ理由からです。

クライアントは、トランザクション内のリソースにアクセスするサーバ上のリモート オブジェクトを呼び出すことができます。これが JDBC リソースであれば、Oracle XA ドライバ (Oracle Thin ドライバまたは Oracle 用の WebLogic Type 4 ドライバ) を使用して JDBCConnectionPool および JDBCTxDataSource をコンフィグレーションし、このデータ ソースから接続を取得できます。または、クライアントで JNDI を使用してデータ ソースをルックアップし、トランザクション内の接続を取得および操作することも可能です。トランザクションの登録は自動的に行われます。


Q. OCIW32.dll エラーの原因は何ですか。

A. Oracle 用 JDBC ドライバを使用すると、「The ordinal 40 could not be loaded in the dynamic link library OCIW32.dll.」というエラー メッセージが表示される場合があります。この問題は、システム ディレクトリにある OCIW32.DLL が旧バージョンであることが原因です。一部のプログラムは、実行時に使用するために、このファイルをシステム ディレクトリにインストールします。このファイルをシステム ディレクトリから削除すれば、このエラーは発生しなくなります。


Q. WebLogic jDriver for Oracle ドライバで Unicode コードセットを使用するにはどうするのですか。

A. Unicode コードセットを使用するには、以下のようにします。

  1. Oracle のインストール時に、適切なコードセットをインストールします。最初のインストール時にコードセットをインストールしなかった場合は、Oracle インストーラを再実行し、適切なコードセットをインストールする必要があります。
  2. JDBC ドライバを実行している環境で、NLS_LANG 変数を定義します。WebLogic Server を起動するシェルで、適切なコードセットを NLS_LANG に割り当てることで定義できます。

インターナショナライゼーションのサポートの詳細については、Oracle 開発者ガイドを参照してください。Unicode の一般的な情報については、「Unicode の Web サイト」を参照してください。Unicode 言語の略称については、「JavaSoft の Web サイト」を参照してください。


Q. WebLogic jDriver for Oracle を使用している場合、ResultSet.getObject() ではどの型のオブジェクトが返されるのですか。

A. WebLogic jDriver for Oracle は、取り出したデータの精度を維持する Java オブジェクトを常に返します。getObject() メソッドでは以下を返します。

たとえば、1.0000 の場合は Integer が返されます。123456789123.00000 のような値の場合は Long が返されます。小数部がゼロでない値の場合、その値の精度を Double で表すことができる場合は Double、それ以外の場合は BigDecimal が返されます。


Q. WebLogic Server で生成される Oracle データベース接続の数を制限するには、どうすればいいですか。

A. クライアントのリクエストに応じて WebLogic Server が生成する Oracle データベース接続の数を制限する場合は、接続プールを使用できます。接続プールを使用すると、複数の T3 アプリケーションで固定数のデータベース接続を共有することができます。接続プールの設定方法については、『WebLogic JDBC プログラマーズ ガイド』を参照してください。


Q. パラメータをとらない Oracle ストアド プロシージャは、どのように呼び出すのですか。

A. 次の構文を使用してください。

  CallableStatement cstmt = conn.prepareCall("Begin procName;
END;");
cstmt.execute();

procName は、Oracle ストアド プロシージャの名前です。これは標準的な Oracle SQL 構文であり、どの Oracle DBMS でも動作します。次の構文も使用できます。

 CallableStatement cstmt = conn.prepareCall("{call procName};");
cstmt.execute();

このコードは、Java 拡張 SQL 仕様に準拠しており、Oracle だけでなくすべての DBMS で動作します。


Q. PreparedStatement の文字列値はどのようにバインドするのですか。

A. 文で String をバインドするために、PreparedStatement クラスを取得しようとしていると仮定します。setString() メソッドは、機能しないように見えます。PreparedStatement は次のように設定されています。

String pstmt = "select n_name from n_table where n_name LIKE '?%'";
PreparedStatement ps = conn.prepareStatement(pstmt);
ps.setString(1, "SMIT");
ResultSet rs = ps.executeQuery();

このコードは機能しません。なぜなら、String で完全な値を指定し (引用符は埋め込まない)、引用符のない疑問符 (?) にバインドする必要があるためです。正しいコードは次のようになります。

  String matchvalue = "smit%";
String pstmt = "select n_name from n_table where n_name LIKE ?";
PreparedStatement ps = conn.prepareStatement(pstmt);
ps.setString(1, matchvalue);
ResultSet rs = ps.executeQuery();

Q. WebLogic jDriver for Oracle を使用し、8 ビット文字セットを使用していますが、期待した文字が表示されません。何が問題なのでしょうか。

A. 8 ビット文字セットの Oracle データベースを Solaris で使用している場合は、クライアントで NLS_LANG を適切な値に設定してください。NLS_LANG を設定しないと、デフォルトで 7 ビット ASCII 文字セットになり、ASCII 128 より大きい文字は適当な文字にマップされます。たとえば、á、à、â はすべて a にマップされます。その他の文字は、疑問符 (?) にマップされます。


Q. Oracle で利用可能なコードセットは、どうしたらわかりますか。

A. Oracle で現在使用できるコードセットを調べるには、SQLPlus からコマンドラインで次の SQL クエリを実行します。

SQL> SELECT value FROM v$nls_valid_values
WHERE parameter='CHARACTERSET';

現在システムにインストールされているすべてのコードセットのリストが返されます。このリストは、次のように表示されます。

  VALUE
-----------------------------------------------------------
US7ASCII
WE8DEC
WE8HP
US8PC437
WE8EBCDIC37
WE8EBCDIC500
WE8EBCDIC285
...

クエリの値を特定のコードセットに制限するには、次のような SQL クエリを使用します。

SQL> SELECT value FROM v$nls_valid_values 
WHERE parameter='CHARACTERSET' and VALUE='AL24UTFFSS';

そのコードセットがインストールされている場合は、次のようなリストが表示されます。

VALUE
-------------------------------------------------------------
AL24UTFFSS

その他のコードセットを追加するには、Oracle のインストール ツールを使用します。詳細については、Oracle にお問い合わせください。


Q. 「ORA」SQLException はどのように調べるのですか。

A. WebLogic jDriver for Oracle アプリケーションで SQLException が生成される場合は、oerr コマンドを使用して Oracle エラーを調べることができます。たとえば、次の SQLException が発生したとします。

java.sql.SQLException: ORA-12536: TNS: operation would block

エラー ORA-12536 の説明は、次のコマンドで表示できます。

> oerr ora 12536

Q. エラー「ORA-6502」は何を意味するのですか。

A. CallableStatement の OUTPUT パラメータにバインドされる文字列のデフォルト長は 128 字です。バインド パラメータに割り当てた値がこの長さを超えると、このエラーが発生します。

バインド パラメータの値の長さは、明示的な長さを scale 引数を使って CallableStatement.registerOutputParameter() メソッドに渡すことによって調節できます。


Q. ORA-12705 のテキストを取り出そうとするとエラーが発生するのはなぜですか。

A. このエラーは、ORACLE_HOME 環境変数を適切に設定していない場合に発生します。WebLogic jDriver for Oracle を使用するには、Oracle クライアント ソフトウェアをインストールし、ORACLE_HOME を設定する必要があります。

システムにインストールされていない言語とコードセットの組み合わせで WebLogic jDriver for Oracle のインターナショナライゼーション機能を使用しようとした場合にも、このエラー メッセージが表示されます。適切なエラー テキストの ORA-12705 エラーが表示される場合は、NLS_LANG を適切に設定していないか、システムに正しいコードセットをインストールしていないかのどちらかです。


Q. Oracle のデータベース リンクを使ってデータベースを更新するとリソースが足りなくなってしまうのはなぜですか。

A. Oracle のデータベース リンクを使用してデータベースを更新する場合、終了時に結果セットと文を閉じても、「maximum number of temporary table locks exceeded」というエラーが表示される場合があります。

データベース リンクは、リモート データベースのテーブルやビューにアクセスできるようにするローカル データベースのオブジェクトです。データベース リンクは Oracle サーバによって管理されるので、ドライバではリソースの使用を管理できません。実際にはリンクが生じて処理が実行されますが (その他のプロセスでは、作成されたレコードが表示可能)、接続が終了するまでリソースは解放されません。データベース リンクを削除し、JDBC ドライバを使用して選択、挿入、および更新を実行することで解決してください。


Q. PreparedStatement クラスを実行すると「TRUNC fails:ORA-00932:inconsistent datatypes」エラーが発生するのはなぜですか。

A. Oracle Metalink Bug Database Doc ID: 144784.1 によれば、暗黙的なデータ型キャストの不存在により、OCI はバインド変数が CHAR データ型であると見なします。SQL 文がバインド変数を DATE データ型として使用し、一方 OCI はそれが CHAR であると考えた場合、SQL パーサにはデータ型の矛盾が発生します。これを解決するには、データ変換関数を明示的に使用して、問題の生じたクエリに含まれるバインド変数を変換します。たとえば、次の選択文字列があるとします。

String st = "select count(*) from simple_table where TRUNC(mydate) = TRUNC(?)"; 

これは、次のように変更する必要があります。

String st = "select count(*) from simple_table where TRUNC(mydate) = TRUNC(TO_DATE(?))"; 

Q. Oracle Blob フィールドはどのように作成および更新するのですか。

A. 次に、Oracle Blob フィールドを作成および更新するサンプル コードを示します。

public void insert() throws SQLException {
try {
 // WebLogic JDBC 接続を使用してデータベースに接続する
Hashtable ht = new Hashtable();
ht.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
ht.put(Context.PROVIDER_URL, "t3://localhost:7001");
InitialContext ctx = new InitialContext(ht);
javax.sql.DataSource ds = (javax.sql.DataSource)
ctx.lookup("java:comp/env/jdbc/DSName");
Connection conn = ds.getConnection();
// この部分は、更新のための選択を行う場合には
// 必須。これを行わないと ORA-1002 が発生する
conn.setAutoCommit (false);
BLOB blob = null;
// 文を作成する
Statement stmt = conn.createStatement ();
// テーブルが存在する場合はドロップする
try {
stmt.execute ("drop table ImageTable");
System.out.println("Table droped ...");
}
catch (SQLException e) {
System.out.println("Table does not exist");
}
// テーブルを作成する
stmt.execute ("create table ImageTable (column1 varchar2(20),
image BLOB)");
System.out.println("Table created ...");
    // テーブル内に BLOB エントリを作成する
stmt.execute("insert into ImageTable values ('one', empty_blob())");
stmt.execute("commit");
System.out.println("inserted empty blob");
String cmd = "select * from ImageTable for update";
ResultSet rset = stmt.executeQuery(cmd);
if (rset.next()) {
blob = ((OracleResultSet)rset).getBLOB(2);
System.out.println("got blob reference");
}
else System.out.println("no row to get!!!!");
rset.close();
blob = readFromFile();
cmd = "update ImageTable set image = ? where column1 = 'one'";
PreparedStatement pstmt = conn.prepareStatement(cmd);
pstmt.setBlob(1, blob);
pstmt.execute();
stmt.execute("commit");
System.out.println("blob updated");
blob = null;
cmd = "select * from ImageTable for update";
rset = stmt.executeQuery(cmd);
if (rset.next()) {
System.out.println("get blob");
blob = ((OracleResultSet)rset).getBLOB(2);
// BLOB で何らかの処理を行う
    }
else
System.out.println("no row to get (2)!!!!");
  }
catch (SQLException sqle) {
System.out.println("SQL Exception occured: " + sqle.getMessage());
sqle.printStackTrace();
  }
catch(FileNotFoundException e) {
System.out.println("File Not Found");
  }
  catch (IOException ioe) {
System.out.println("IO Exception" + ioe.getMessage());
  }
catch (Exception ioe) {
System.out.println("Exception" + ioe.getMessage());
  }
}

Q. Oracle XAResource はどのように登録するのですか。

A. このコードは、サーバ サイドでのみ動作します。クライアントでは実行できません。また、通常この登録は、XAResource を実装する JDBC リソースに対して透過的に実行される点にも注意してください。

// Oracle の XAResource
String URL = "jdbc:oracle:thin:@DbmsHost:DbmsPort:DbmsName";
DriverManager.registerDriver(new OracleDriver());
// XA 接続を作成する
OracleXADataSource oxds1 = new OracleXADataSource();
oxds1.setURL(URL);
oxds1.setUser("scott");
oxds1.setPassword("tiger");
javax.sql.XAConnection pc1 = oxds1.getXAConnection();
m_oracleResource = pc1.getXAResource ();
m_oracleConnection = pc1.getConnection();
// TM を取得するためのソース コード
Context ctx = null;
Hashtable env = new Hashtable();
env.put(Context.INITIAL_CONTEXT_FACTORY,
"weblogic.jndi.WLInitialContextFactory");
// WebLogic Server 用のパラメータ
// 環境に合わせて適切なホスト名、ポート番号、
// ユーザ名、およびパスワードに置き換える
env.put(Context.PROVIDER_URL, "t3://localhost:7001");
env.put(Context.SECURITY_PRINCIPAL, "system");
env.put(Context.SECURITY_CREDENTIALS, "managers");
ctx = new InitialContext(env);
m_tManager =
(TransactionManager)ctx.lookup("javax.transaction.TransactionManager");
//TM を登録するためのソース コード
m_tManager.begin();
m_transaction = m_tManager.getTransaction();
weblogic.transaction.TransactionManager weblogicTManager =
((weblogic.transaction.TransactionManager) m_tManager);
weblogicTManager.registerStaticResource("oracle",m_oracleResource);
// リソースをトランザクションに登録する
m_transaction.enlistResource(m_oracleResource);

Q. 「ORA-00600」が発生するのはなぜですか。

A. 通常、このエラーは Oracle サーバのバージョンが使用しているドライバのバージョンより新しいことを表します。Oracle Thin ドライバを使用している場合は、Oracle から最新の ojdbc14.jar をダウンロードし、これを CLASSPATH の冒頭に追加する必要があります (できれば、startweblogic.cmd など、サーバを起動するスクリプトもすべて更新してください。これらのスクリプトは CLASSPATH をオーバーライドします)。


Q. 「ORA-24327」が発生するのはなぜですか。

A. 通常、このエラーは ORACLE_HOME 環境変数が設定されていない場合、誤って設定されている場合、D_LIBRARY_PATH または PATH に正しいダイナミック リンク ライブラリが含まれていない場合に発生します。また、サポートされていないバージョンの Oracle クライアント ソフトウェアで weblogic.jdbc.oci.Driver を使用しようとした場合にもこのエラーが発生します。この場合は、代わりに Oracle Thin ドライバを使用してください。


Q. 「java.sql.SQLException: getOBJECT is not supported by the WebLogic JDBC Driver」が発生するのはなぜですか。

A. WebLogic JDBC 接続プールと weblogic.jdbc.vendor.oracle.OracleResultSet を使用するとこのエラーが返されます (OBJECT には Oracle オブジェクトの名前が表示されます)。このエラーは、オブジェクト型がシリアライズ可能でないため、この機能が WebLogic Server JDBC でサポートされないことを表します。これを回避する方法は 2 つあります。


Q. SET TRANSACTION を使用すると「ORA-01453」が発生するのはなぜですか。

A. Oracle を使用していると、「java.sql.SQLException: ORA-01453: SET TRANSACTION must be first statement of transaction」というメッセージがログに記録されることがあります。この問題は Oracle インタフェースの制約によるもので、Oracle 8.1.7 以降で発生します。WebLogic では、モードがすでに現在の状態に一致している場合は SET TRANSACTION を呼び出さないようにすることで、問題を最小限に抑えるようにしています。

 

フッタのナビゲーションのスキップ  ページの先頭 前 次