• 検索結果がありません。

省資源・高性能アプリケーション作成のために

第2章 アプリケーションの設計

2.6 省資源・高性能アプリケーション作成のために

以下の例ではResultSetインタフェースを使用し、データを更新しています。

(1) ResultSetによる更新を可能にする設定を行います。

(2) SQL文を実行して、ResultSetオブジェクトを生成します。

(3) カーソルの位置を最終行まで1行ずつ移動します。

(4)位置づけている行の“価格”列の値を取得します。

(5) 位置づけている行の“価格”列の値を更新します。

(6) データベースを更新します。

2.6.2 ステートメントキャッシュ

ステートメントキャッシュとは

繰り返し実行されるループやメソッドの中でSQL文の準備、実行および解放が行われると、そのつど文の解析と作成およ びカーソルの作成が行われます。

このような場合に、SQL文をキャッシュして再利用することで性能を向上させる機能です。

ステートメントキャッシュを利用すると、次のメリットがあります。

・ 定型SQL文を繰り返し実行する場合に性能が向上します。

・ コネクションプーリング機能と組み合わせることで、コネクションが再利用された時に、以前のコネクションでキャッシュ していたSQL文が有効となるため、性能が向上します。

ステートメントキャッシュの仕組み

ステートメントキャッシュ機能は、prepareStatementメソッドまたはprepareCallメソッドで実行されたSQL文をキャッシュの対 象にします。

ステートメントキャッシュ機能を有効にすると、以下のような動作となります。

1. prepareStatementメソッドまたはprepareCallメソッドが実行されて、SQL文が作成されたときにキャッシュに登録しま

す。

2. PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが実行された、またはガー ベジコレクションされたとき、キャッシュに登録されているSQL文を再利用可能な状態にします。

3. 以降、prepareStatementメソッドまたはprepareCallメソッドが実行されるとキャッシュからSQL文を取り出して再利用し ます。

JDBCドライバはSQL文をキーにして同じSQL文かどうかを判断し、キャッシュを再利用します。以下の条件をすべて満足 する場合に、同じSQL文であると判断します。

・ アプリケーションで指定されたSQL文の文字列が同じであること

(SQL文の大文字と小文字は区別されます。たとえば、“SELECT”と“select”は別の文字列として認識されます)

・ StatementオブジェクトやPreparedStatementオブジェクト作成時に指定された、ResultSetのタイプが同じであること

・ StatementオブジェクトやPreparedStatementオブジェクト作成時に指定された、ResultSetの並行処理が同じであること

キャッシュへのSQL文の登録は、SQL文を実行した順番に行います。

ステートメントキャッシュに登録することができるSQL文の上限値は、データソースオプション設定画面の「ステートメント キャッシュ数」で設定します。

実行したSQL文の数が、「ステートメントキャッシュ数」に設定した値に達した場合、それ以降実行するSQL文はキャッシュ しません。

データソースオプション設定画面の詳細については、“5.2.3 JDBCデータソース登録ツール”を参照してください。

性能が向上するケース

性能が向上するケースについて、記述例をもとに以下に説明します。

ケース1

PreparedStatement pstmt1 = null; (1) ResultSet rs1 = null; (2) pstmt1 = con.prepareStatement("SELECT ID,NAME (3) FROM GENERAL.EMPLOYEE WHERE ID=?");

pstmt1.setInt(1, iNumber); (4) rs1 = pstmt1.executeQuery(); (5) :

rs1.close(); (6) pstmt1.close(); (7)

以降、(3)~(7)の処理を繰り返し実行する。

上記のように、繰り返し実行される処理の中で、処理(3)のprepareStatementメソッドを毎回実行している場合、2回目 以降はキャッシュに登録されたSQL文が再利用されるため、SQL文の解析と作成およびカーソルの作成が行われな くなり、性能が向上します。

ケース2

PreparedStatement pstmt1 = null; (1) ResultSet rs1 = null; (2) pstmt1 = con.prepareStatement("SELECT ID,NAME (3) FROM GENERAL.EMPLOYEE WHERE ID=?");

pstmt1.setInt(1, iNumber); (4) rs1 = pstmt1.executeQuery(); (5) :

rs1.close(); (6) pstmt1.close(); (7) 以降、(4)~(6)の処理を繰り返し実行する。

上記のように、繰り返し実行される処理の外で、処理(3)のprepareStatementメソッドを一度しか実行しない場合、コネ クションプーリング機能と組み合わせることで、コネクションが再利用されたときに、以前のコネクションでキャッシュしていた SQL文が有効となるため、性能が向上します。

使用メモリ量について

ステートメントキャッシュ機能はSQL文をキャッシュするため、通常に比べてメモリ使用量が増加します。

使用するメモリ量については、以下を目安にしてください。

1文当たりのメモリ増加量 = 約100Kbyte

参照

アプリケーション全体のメモリ使用量については、“Interstage Application Server インストールガイド”を参照してください。

自動クローズオプション

PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが指定されている場合、ステート メントキャッシュ機能は、キャッシュに登録されたSQL文を再利用可能な状態にします。

しかし、closeメソッドを省略してガーベジコレクションにクローズを任せている場合には、キャッシュに登録されたSQL文を 再利用可能な状態にするのが不定期となります。性能を向上するためには、アプリケーションでcloseメソッドを記述する 修正が必要になります。

Symfoware ServerのJDBCドライバでは、アプリケーションを修正せずに自動クローズオプションを指定することで、以下 の条件の場合にcloseメソッドを自動的に実行します。

1. PreparedStatementインタフェースまたはCallableStatementインタフェースのcloseメソッドが実行されていない状態 2. prepareStatementメソッドまたはprepareCallメソッドで同一のSQL文を指定

3. 結果セットのタイプが同じ

4. 結果セットの並行処理の種類が同じ

自動クローズオプションは、データソースオプション設定画面の「ステートメント自動クローズ」で設定することができます。

データソースオプション設定画面の詳細については、“5.2.3 JDBCデータソース登録ツール”を参照してください。

実行したSQL文の数が、「ステートメントキャッシュ数」で設定されたキャッシュ数に達した場合、以降実行されるSQL文は キャッシュしませんが、自動クローズの対象にもなりません。

注意

以下の記述例の処理(5)と(6)のように、prepareStatementメソッドで同一のSQL文を重複して使用している場合は、自動ク ローズオプションを使用しないでください。以下の例で自動クローズオプションを指定すると、処理(6)で処理(5)のSQL文 がクローズされてしまい、処理(7)でエラーが発生します。

PreparedStatement pstmt1 = null; (1) PreparedStatement pstmt2 = null; (2) ResultSet rs1 = null; (3) ResultSet rs2 = null; (4) pstmt1 = con.prepareStatement("SELECT ID,NAME (5) FROM GENERAL.EMPLOYEE WHERE ID=?");

pstmt2 = con.prepareStatement("SELECT ID,NAME (6) FROM GENERAL.EMPLOYEE WHERE ID=?");

pstmt1.setInt(1, iNumber); (7) rs1 = pstmt1.executeQuery(); (8) :

pstmt2.setInt(1, iNumber2); (9) rs2 = pstmt2.executeQuery(); (10) :

MAX_SQLまたはCLI_MAX_SQLとの関係

MAX_SQLまたはCLI_MAX_SQLを超える数のステートメントキャッシュをすることはできません。MAX_SQLまたは CLI_MAX_SQLを超えた場合には、アプリケーション実行時にエラーとなる場合があります。

MAX_SQLまたはCLI_MAX_SQLには、データソースオプション設定画面の「ステートメントキャッシュ数」で指定した数

よりも大きい値を設定してください。

参照

MAX_SQLについては、“アプリケーション開発ガイド(共通編)”の“クライアント用の動作環境ファイル”を参照してくださ い。

CLI_MAX_SQLについては、“5.2.3.4 ctuneparamオプションについて”を参照してください。

2.6.3 行識別子(SQL ROWID)を利用したデータ操作

ここでは、行識別子の概要と注意事項について説明します。

行識別子

(SQL ROWID)

とは

行識別子は、データベース中の任意の表の行を一意に識別するためのものです。Symfoware Serverにおける行識別子 は、“ROW_ID”で表します。行識別子は、問合せ指定の選択リストに指定して値を取り出すことができます。取り出した 行識別子は、以下の探索条件に指定して任意の行を操作するために使用します。

・ UPDATE文:探索の探索条件

・ DELETE文:探索の探索条件

・ 問合せ指定のWHERE句の探索条件

行識別子を使用することにより、データベース中の単一行を高速に操作することができます。また、あらかじめ検索した 集合の任意の行を一意に識別して操作することができます。

行識別子を使用して行の更新を行います。

行識別子使用時の注意

行識別子を使用する場合の注意事項を、以下に示します。

・ 行識別子を使用する場合には、JDK6とJDBC4.Xドライバの組合せが必要になります。

・ 問合せ指定で取り出した行識別子を、SQLデータ操作文のWHERE句の探索条件に指定する場合、SQLデータ操 作文は、行識別子を取り出した問合せ指定と同じ表を操作する必要があります。取り出した行識別子を、異なる表を 操作するデータ操作の探索条件に指定すると、検索データは見つかりません。

・ 取り出した行識別子は、そのトランザクション内で再検索または更新に使用することができます。ただし、トランザクショ ンの独立性水準により同一トランザクション内においても、同じデータを検索、もしくは、異なる行を更新してしまうこと があります。

独立性水準 同一行の操作

SERIALIZABLE 同一行の操作を保証します。

REPEATABLE READ 同一行の操作を保証します。

READ COMMITTED 以下のいずれかの条件で取得した行識別子は、再検

索で異なる行を識別することがあります。

・トランザクションアクセスモードがREAD ONLY

・カーソルの更新可能性句がREAD ONLY READ

UNCOMMITTED

再検索で異なる行を識別することがあります。

・ 取り出した行識別子を、他のトランザクションで再検索または更新に利用すると、同じデータを検索、または、異なる 行を更新することがあります。このような場合は、行識別子を取り出したときに行のデータも同時に取り出しておき、行 識別子を利用して更新する前に、行識別子で再検索して行のデータが他のトランザクションにより変更されていない かどうかを調べる必要があります。

事象 原因

検索データなし 該当行が、他のトランザクションにより削除または更新されています。

前回の検索結果 と値が異なる

・ 他のトランザクションにより行が更新されています。

・ 他のトランザクションにより行が削除されたあと、別の行が挿入されています。

参照

行識別子を指定可能な箇所についての詳細は、“SQLリファレンス”を参照してください。