RowSetの特徴と使用方法を説明します。RowSetが実装されています。仕様の詳細は、http://www.oracle.com/technetwork/java/javase/jdbc/index.htmlを参照してください。WebLogicのRowSet実装には、RowSet仕様の拡張も含まれています。した拡張を使用すると、アプリケーションでRowSetをより有効に活用できます。ResultSetの拡張です。ResultSetと同様、RowSetも表形式のデータを保持するJavaオブジェクトです。RowSetではResultSet機能に大幅な柔軟性が加えられていて、ResultSetの持つ制限の一部が緩和されたり削減されたりしています。ServerのRowSet実装には、以下のような種類とユーティリティがあります。ServerのRowSet実装は、ユーザーが以下の手順でRowSetを扱うことを想定して設計されています。RowSetを作成して構成します(問合せ、データベース接続、その他のプロパティを定義します)。RowSetにデータを入力します(問合せパラメータを指定して問合せを実行します)。必要に応じてRowSetメタデータを指定します。必要に応じてRowSetにフィルタまたはソーターを設定します。RowSet内のデータを操作します(挿入、更新、削除を行います)。RowSetからデータベースへのデータ変更の同期を行います。変更を同期した後には、アプリケーションの設計に応じて手順2または手順3から繰返し処理を行えます。RowSetの再利用」を参照してください。WebLogicのRowSet実装にはライフ・サイクルのフレームワークがあり、これによってRowSetオブジェクトが異常な状態にならないようにしています。Serverでは、上記の処理段階に応じて、内部的にRowSetに対しライフ・サイクルのステージが設定されます。データ損失のリスクを減らすため、ライフ・サイクルのステージに応じてRowSetに実施できる操作が制限されます。RowSetのステージが「Updating」(更新)の場合、RowSetに対して呼び出せるのは、updateXXX()メソッド(updateString()、updateInt()など)のみです。この制限は、updateRow()を呼び出して更新のフェーズが完了するまで適用されます。重要な注意事項を以下に示します。保留中の変更がある場合、RowSetに対して再入力、フィルタ、ソートは行えません。データの変更が不測の事態によって失われることを防ぐため、RowSetのデータを変更してもその変更がデータベースとの間で同期されていない場合はRowSetに対してこれらの操作ができないようになっています。カーソルが暗黙的に移動することはありません。行から行へ明示的にカーソルを移動する必要があります。RowSetのライフ・サイクルのステージは内部的なプロセスです。ライフサイクルのステージにアクセスするためのパブリックAPIはありません。ライフサイクルのステージをユーザーが設定することはできません。acceptChanges()またはrestoreOriginal()を呼び出すとRowSetのライフ・サイクルのステージは終了し、再び処理を開始できます。注意:クライアント側アプリケーションでRowSetを使用する際は、サーバーとクライアントの両方のCLASSPATHに、同一のJDBCドライバ・クラスを指定する必要があります。ドライバ・クラスが一致していないと、java.rmi.UnmarshalException例外がスローされる場合があります。RowSetの作成時からデータ変更がデータベースとの間で同期されるまでのRowSetのライフ・サイクル・ステージの実例については、例8-1のコメントを参照してください。Serverにおける標準のCachedRowSetの使い方について説明します。特性CachedRowSetに特有のプログラミング上の考慮事項と制限サンプル・コードCachedRowSetのクラスとインタフェースのインポートCachedRowSetの作成CachedRowSetのプロパティの設定データベース接続のオプションCachedRowSetへの入力CachedRowSetへのメタデータの設定CachedRowSetのデータの操作RowSetの変更をデータベースとの間で同期するまた、標準のCachedRowSetオブジェクトのWebLogic拡張の使用方法については、「WLCachedRowSet」を参照してください。特性CachedRowSetは接続されていないResultSetオブジェクトです。CachedRowSetのデータはメモリーに格納されます。Server実装のCachedRowSetには以下の特性があります。データの挿入、更新、削除に使用できます。シリアライズ可能なため、モバイル機器などの様々なアプリケーション・コンポーネントに渡すことができます。トランザクション処理に対応しているためRowSetを再利用できます。RowSetの再利用」を参照してください。RowSetでのデータ変更をデータベースとの間で同期するためにオプティミスティックな同時実行性制御が使用されます。SyncProvider例外から得られるSyncResolverオブジェクトを使用して、RowSetでのデータ変更とデータベース間の競合を解決します。「SyncResolverを使用したSyncProviderExceptionの処理」を参照してください。CachedRowSetに特有のプログラミング上の考慮事項と制限アプリケーションの設計時には、次のことを考慮するようにします。RowSetの問合せ結果はすべてメモリーに格納されるデータの競合RowSetの問合せ結果はすべてメモリーに格納されるCachedRowSetではデータベースへの接続が保持されないので、すべての問合せの結果は必ずメモリーに格納されます。問合せの結果が非常に大きいと、メモリー不足エラーによりパフォーマンスが低下することがあります。大きなデータ・セットの場合、ResultSetを使用する方が適していることもあります。ResultSetではデータベースへの接続が保持されるため、問合せ結果の一部をメモリーに保持してから必要に応じてデータベースに戻り、さらに行を取得できるためです。データの競合CachedRowSetは、RowSetへの入力からRowSet内のデータ変更がデータベースとの間で同期されるまでの間に、別のプロセスで更新されることがあまりないようなデータに使用するのがもっとも適しています。この期間にデータベースが変更されるとデータの競合が発生します。データの競合を検出して処理する方法については、「SyncResolverを使用したSyncProviderExceptionの処理」を参照してください。サンプル・コード例8-1にCachedRowSetの基本的なワークフローを示します。この例では、主要な各操作と対応するRowSetのライフ・サイクル・ステージについてコメントを使って説明します。このサンプル・コードの後で、サンプルの主要な各セクションについてさらに詳細に説明します。}}CachedRowSetのクラスとインタフェースのインポート標準のRowSetを使用するには、次のクラスをインポートする必要があります。javax.sql.rowset.CachedRowSet;weblogic.jdbc.rowset.RowSetFactory;CachedRowSetの作成RowSetはファクトリ・インタフェースから作成されます。ServerでRowSetを作成するには、主に以下の手順に従います。RowSetFactoryインスタンスを作成します。このインスタンスはアプリケーションで使用するRowSetオブジェクトを作成するためのファクトリとして機能します。RowSetFactoryのデータベース接続のプロパティを指定すると、同じデータベース接続を使用する複数のRowSetを少ないコード行で作成できます。RowSetFactory.newInstance();WLCachedRowSetを作成してjavax.sql.rowset.CachedRowSetオブジェクト型にキャストします。RowSetFactoryメソッドでWLCachedRowSetオブジェクトが作成されます。このオブジェクトをそのまま使用することもできますが、標準のCachedRowSetオブジェクトを使用する場合は、オブジェクトをCachedRowSetとしてキャストできます。rsfact.newCachedRowSet();CachedRowSetのプロパティの設定RowSetには、同時実行性の種類、データ・ソースの名前、トランザクション分離レベルなど数多くのプロパティがあります。これらのプロパティを設定してRowSetの動作を決定できます。RowSetの特定の用途に応じて必要なプロパティのみを設定する必要があります。利用可能なプロパティの詳細は、http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/BaseRowSet.htmlのjavax.sql.rowset.BaseRowSetクラスのJavadocを参照してください。データベース接続のオプションほとんどのアプリケーションでは、データベースからのデータをRowSetに入力します。RowSetとデータベースとの接続は、以下のいずれかの方法で設定します。setDataSourceName()メソッドを使用して、JDBCデータ・ソースのJNDI名を指定できます。execute()およびacceptChanges()を呼び出すと、RowSetでデータ・ソースからのデータベース接続が取得され、それが使用されて、データ・ソースの接続のプールに戻されます。これは、推奨される方法です。RowSetで必要になる前にアプリケーションでデータベース接続を取得してから、接続オブジェクトをexecute()メソッドおよびacceptChanges()メソッドのパラメータとして渡します。必要に応じて接続を閉じる必要もあります。JDBCデータ・ソースの詳細については、「DataSourceオブジェクトからのデータベース接続の取得」を参照してください。JDBCドライバをロードして適切なプロパティを設定すると、RowSetではexecute()およびacceptChanges()を呼び出したときにデータベース接続が作成されます。RowSetでは接続を使用し終えるとすぐにその接続が閉じられます。RowSetではexecute()メソッド呼出しとacceptChanges()メソッド呼出しの間、接続は保持されません。RowSetFactoryのデータベース接続のプロパティを設定すると、RowSetFactoryから作成されたすべてのRowSetでその接続のプロパティが継承されます。データ・ソースをルックアップしてからsetDataSource()メソッドでRowSetFactoryのデータ・ソースのプロパティを設定するのが、推奨される方法です。RowSetFactoryrsfact.setDataSource(ds);CachedRowSetへの入力RowSetへのPopulating(入力)とは、RowSetにデータの行を格納する作業のことをいいます。通常、このデータの取得元はリレーショナル・データベースです。データベースからのデータは、以下のいずれかの方法でRowSetに入力できます。setCommand()メソッドでSQLコマンドを設定してから、execute()メソッドでそのコマンドを実行します。PHYSICIAN");rs.execute();既存の結果セットからpopulate()メソッドを使用して入力します。rs.populate(resultSet);注意:ResultSet.TYPE_FORWARD_ONLYの結果セットを使用している場合、以下の条件で行セットに入力しようとするとSQLExceptionがスローされます。rs)を呼び出した場合。newPosition)を呼び出した場合。CachedRowSetへのメタデータの設定RowSetのデータ変更をデータベースとの間で同期するために、RowSetにメタデータを設定することが必要な場合もあります。詳細については、「RowSetに対するデータベース更新用メタデータの設定」を参照してください。CachedRowSetのデータの操作キャッシュされたRowSetに一連のデータ行を入力した後には、結果セットのデータを扱うのとほぼ同じ方法でそのキャッシュ済みのデータを取り扱えます。データベースに対して変更を行う前には、acceptChanges()を明示的に呼び出す必要があります。注意:RowSetの列名や表名に区切り識別子は使用できません。SQL文の中では、区切り識別子は二重引用符で囲む必要があります。区切り識別子には、SQL予約語(USERやDATEなど)になっているものや、識別子ではない名前になっているものがあります。有効な識別子は必ず文字で始まり、文字、数字、およびアンダースコアのみを使用できます。RowSetの行からデータを取得するRowSetからデータを取得するには、結果セットの場合と同様にgetXXXメソッドを使用します。}RowSetの行を更新する通常、データの更新は以下の手順で行います。行または挿入行に移動します。updateXXXメソッドで行を変更します。updateRow()またはinsertRow()で操作を完了します。操作を完了しても変更はデータベースとの間で同期されないことに注意します。変更はRowSetに対してのみ行われます。acceptChanges()を呼び出して、明示的に変更を同期させる必要があります。詳細については、下記の「RowSetの変更をデータベースとの間で同期する」を参照してください。Serverでは内部的に各操作の後でRowSetにライフ・サイクルのステージが設定され、その後は現在のライフ・サイクルのステージに基づいてRowSetに対する以降の操作が制限されます。updateメソッド群で行の変更を開始したら、必ずupdateRow()またはinsertRow()で操作を完了します。完了してはじめて、別の行の操作(別の行へのカーソルの移動を含む)ができるようになります。RowSetのライフ・サイクルのステージと、各ステージで許可される操作の詳細については、「RowSetを使用したプログラミング」を参照してください。行を更新するには、更新する行にカーソルを移動して、その行の個別の列に対してupdateXXXメソッドを呼び出してから、updateRow()を呼び出して操作を完了します。"Francis");rs.updateRow();注意:複数の表の同名の列を更新する場合、列の参照にはUpdate文で列の索引番号を使用する必要があります。RowSetに行を挿入する行を挿入するには、新規の挿入行にカーソルを移動してその行の列の値を更新してから、insertRow()を呼び出してRowSetに行を追加します。"Yuri@poet.com");rs.insertRow();rs.moveToCurrentRow();行を挿入した後には、明示的にカーソルを移動する必要があります。カーソルが暗黙的に移動することはありません。RowSetの行を削除するRowSetの行を削除するには、カーソルをその行に移動してdeleteRow()を呼び出します。例:rs.last();rs.deleteRow();RowSetの変更をデータベースとの間で同期するRowSetの個別の行を変更した後には、acceptChanges()を呼び出して変更をデータベースに伝播します。例:rs.acceptChanges();acceptChanges()を呼び出すと、RowSetでは、すでにRowSetで使用されているデータベース接続情報を使用するか(「データベース接続のオプション」を参照)、acceptChanges(connection)メソッドで渡された接続オブジェクトを使用して、データベースに接続します。1つまたは複数の行を変更した後にacceptChanges()を呼び出せます。RowSetに対してすべての変更を行った後にacceptChanges()を呼び出すと、RowSetからデータベースへの接続が1度だけになるのでより効率的です。ServerでRowSetを使用する場合、データベースに対する書込みと読取りにはweblogic.jdbc.rowset.WLSyncProviderオブジェクトが内部的に使用されます。WLSyncProviderではデータベースの変更にオプティミスティックな同時実行性が使用されます。RowSetへの入力時からRowSetのデータの変更がデータベースに伝播されるまでの間に、データベースのデータが別のプロセスによって変更されないと仮定されます。データベースに変更を書き込む前には、WLSyncProviderによってデータベースのデータとRowSetの元の値(RowSetの作成時または最後の同期の際にRowSetに読み込まれた値)が比較されます。データベースの値になんらかの変更があった場合にはjavax.sql.rowset.spi.SyncProviderExceptionがスローされ、データベースにはどの変更も書き込まれません。アプリケーションでこの例外を捕捉して、処理方法を決定できます。詳細については、「SyncResolverを使用したSyncProviderExceptionの処理」を参照してください。WLCachedRowSetインタフェースはCachedRowSetインタフェースの拡張で、このインタフェースでオプティミスティックな同時実行性ポリシーを選択できます。詳細については、「オプティミスティックな同時実行性ポリシー」を参照してください。変更をデータベースに伝播した後には、アプリケーションの環境に応じてRowSetのライフ・サイクルのステージがDesigning(設計)またはPopulating(入力)に変わります。Designing(設計)ステージの場合、再び使用する前にRowSetに再入力する必要があります。Populating(入力)ステージの場合、現在のデータを持つRowSetを使用できます。RowSetの再利用」を参照してください。RowSetを再び使用する予定がない場合は、close()メソッドで閉じる必要があります。例:rs.close();RowSetに対するデータベース更新用メタデータの設定SQL問合せでRowSetに入力する場合、WebLogicのRowSet実装ではResultSetMetaDataインタフェースを使用して、自動的にRowSet内のデータの表名と列名が認識されます。ほとんどの場合、RowSetが変更をデータベースに書き戻すために必要なSQLを生成するには、この情報で十分です。一部のJDBCドライバでは、この問合せで返される行に表および列のメタデータが含まれません。RowSetのデータ変更をデータベースとの間で同期しようとすると、次のエラーが表示されます。column.表名がない場合、RowSetは読込み操作にのみ使用できます。表名をプログラム的に指定しない限り、RowSetでは更新を発行できません。setKeyColumns()メソッドによる主キー列の設定が必要な場合もあります。});詳細については、javax.sql.rowset.CachedRowSetインタフェースの説明を参照してください。RowSet拡張について説明します。書込み表の設定executeAndGuessTableNameとexecuteAndGuessTableNameAndPrimaryKeysSQL問合せでRowSetに入力する場合、通常はexecute()メソッドを使用して問合せを実行し、データを読み込みます。WLCachedRowSet実装には、関連付けられた表のメタデータも識別するためにexecuteメソッドを拡張したexecuteAndGuessTableNameメソッドおよびexecuteAndGuessTableNameAndPrimaryKeysメソッドが用意されています。executeAndGuessTableNameメソッドでは、関連付けられたSQLを解析して、すべての列の表名を、SQLキーワードFROMに続く最初の語として設定します。executeAndGuessTableNameAndPrimaryKeysメソッドは、SQLコマンドを解析して表名を読み取ります。続いて、java.sql.DatabaseMetaDataを使用して表の主キーを判定します。注意:これらのメソッドはDBMSまたはJDBCドライバのサポートに依存しています。すべてのDBMS、すべてのJDBCドライバで機能するとは限りません。MetaDataインタフェースを使用した表および主キー情報の設定WLRowSetMetaDataインタフェースを使用して表および主キー情報を手動で設定することもできます。"employees");WLRowSetMetaDataインタフェースを使用して主キー列を指定することもできます。true);詳細については、weblogic.jdbc.rowset.WLRowSetMetaDataのJavadocを参照してください。書込み表の設定WLRowSetMetaDataインタフェースには、更新または削除する表のみを指定するためのsetWriteTableNameメソッドがあります。このメソッドは通常、複数の表の結合が入力されているRowSetにおいて、1つの表のみを更新する場合に使用します。書込み表に属さない列は読取り専用としてマークされます。RowSetに「注文」と「顧客」の結合が含まれるとします。書込み表を「注文」に設定します。deleteRowを呼び出すと、「注文」の行は削除されますが、「顧客」の行は削除されません。(http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/CachedRowSet.html#setTableName(java.lang.String)を参照)を提供します。どちらのメソッドを呼び出しても、書込み表に属さない列が読取り専用のものとしてマークされます。WebLogicではまた、列がどの表に属するかのマッピングに使用されるCachedRowSetMetaData.setTableNameメソッドが用意されています。setTableNameを使用して書込み表を設定する際には、アプリケーションに適したAPIを使用してメソッドを実装するように注意してください。RowSetとトランザクションほとんどのデータベースやJDBCアプリケーションではトランザクションを使用します。RowSetはJTAトランザクションを含むトランザクションをサポートしています。一般的な使用例は次のとおりです。トランザクション1でRowSetを取得します。トランザクション1がコミットされます。基底のデータに対して、データベースやアプリケーション・サーバーによるロックはありません。RowSetはメモリー内にデータを保持します。データを変更したり、ネットワーク経由でクライアントに提供したりできます。アプリケーションはデータベースに対する変更をコミットする場合、トランザクション2を開始して、RowSetのacceptChangesメソッドを呼び出します。その後トランザクション2がコミットされます。JTAグローバル・トランザクションとの統合EJBコンテナとUserTransactionインタフェースはJTAトランザクション・マネージャを使用してトランザクションを開始します。RowSetの操作はこのトランザクションに参加することができます。(TxDataSource)を使用する必要があります。Serverコンソールで構成できます。acceptChangesでオプティミスティックな競合や他の例外が発生した場合、RowSetはグローバルJTAトランザクションを中止します。アプリケーションは通常データを再び読み込んで、新しいトランザクションで更新を再び処理します。障害またはロールバックが発生すると、データはデータベースからロールバックされますが、RowSetからはロールバックされません。作業を進める前に、次のいずれかを行う必要があります。rowset.refreshを呼び出して、データベースからのデータでRowSetを更新します。現在のデータで新しいRowSetを作成します。ローカル・トランザクションの使用JTAグローバル・トランザクションを使用しない場合、RowSetはローカル・トランザクションを使用します。最初に接続に対するsetAutoCommit(false)を呼び出します。次にSQL文をすべて発行して、最後にconnection.commit()を呼び出します。これでローカル・トランザクションをコミットしようとします。EJBまたはJMSコンテナによって開始されたJTAトランザクションと統合する場合は、このメソッドは使用しないでください。acceptChangesでオプティミスティックな競合や他の例外が発生した場合、RowSetはローカル・トランザクションをロールバックします。この場合、acceptChangesで発行されたSQLは、いずれもデータベースにコミットされません。ローカル・トランザクションを使用するRowSetの動作この節では、失敗したローカル・トランザクションにおけるRowSetの動作について説明します。この動作は、接続オブジェクトの種類によって異なります。connection.commitの呼出しこの状況では、接続オブジェクトはRowSetによって作成されたものではなく、connection.commitを呼び出すことによってローカル・トランザクションを開始します。トランザクションが失敗するか、または接続がconnection.rollbackを呼び出すと、データはデータベースからロールバックされますが、RowSetにおいてはロールバックされません。作業を進める前に、次のいずれかを行う必要があります。rowset.refreshを呼び出して、データベースからのデータでRowSetを更新します。現在のデータで新しいRowSetを作成します。acceptChangesの呼出しこの状況では、RowSetが独自の接続オブジェクトを作成し、それを使用してacceptChangesを呼び出すことによりRowSet内のデータを更新します。障害が発生した場合、またはRowSetがconnection.rollbackを呼び出した場合、データはRowSetからもデータベースからもロールバックされます。多くの場合、RowSetの変更をデータベースとの間で同期した後に、そのRowSetを現在入力されているデータのまま使用することが必要になるでしょう。することでデータベースとの往復回数が減るため、アプリケーションのパフォーマンスを向上させることができます。RowSetとそのデータを再利用する場合、そのデータにさらに変更を加える前に、そのRowSetが参加するトランザクションが必ずすべて完了している必要があります。ローカル・トランザクションでRowSetを使用していて、RowSetデータの変更をデータベースとの間で同期する前に、接続オブジェクトにautocommit=trueと設定されている場合、データの同期後に現在の値のままRowSetを再利用できます。これは、autocommitの設定によってローカル・トランザクションがすぐに強制的に完了するためです。RowSetの変更前には、ローカル・トランザクションが必ず完了します。以下のいずれかの状況でRowSetを使用している場合、すべてのトランザクションが必ず自動的に完了するとは限りません。グローバル・トランザクションで使用しているローカル・トランザクションで、autocommit=falseと設定された接続オブジェクトを使用してデータの変更をデータベースと同期しているこれらのいずれかの場合、現在のデータでRowSetを再利用する前に、acceptChanges()を呼び出してデータベースとの間で変更を同期した後で、tx.commit()またはjava.sql.Connection.commit()の代わりにjavax.sql.rowset.CachedRowSet.commit()を呼び出してトランザクションをコミットします。CachedRowSet.commit()メソッドにはConnection.commit()メソッドがラップされています。これを使用すると必ずトランザクションが完了され、その後にRowSetを変更できるようになります。Serverにおける標準のFilteredRowSetの使い方について説明します。特有のプログラミング上の考慮事項FilteredRowSetのサンプル・コードFilteredRowSetのクラスとインタフェースのインポートFilteredRowSetの作成FilteredRowSetのプロパティの設定FilteredRowSetのデータベース接続のオプションFilteredRowSetへの入力FilteredRowSetのメタデータの設定FilteredRowSetに対するフィルタの設定FilteredRowSetのデータの操作FilteredRowSetの特性FilteredRowSetを使用するとキャッシュされた行のサブセットを取り扱え、データベースに接続されていない状態で行のサブセットを変更できます。フィルタ処理されたRowSetとは、分かりやすく言えば、キャッシュされているRowSetの中で、特定の行のみを閲覧、移動、操作できるものをいいます。FilteredRowSetには以下のような特性があります。利用できる行は、アプリケーションで指定したjavax.sql.rowset.Predicateオブジェクトで決定され、setFilter()メソッドで指定されます。Predicateオブジェクトにはjavax.sql.rowset.Predicateインタフェースを実装する必要があります。rs)メソッドがあり、このメソッドでRowSetの各行を評価します。このメソッドからtrueが返された場合、その行は利用可能で閲覧することもできます。このメソッドからfalseが返された場合、その行は利用も閲覧もできません。詳細については「FilteredRowSetに対するフィルタの設定」を参照してください。Serverにはweblogic.jdbc.rowset.SQLPredicateクラスというjavax.sql.rowset.Predicateインタフェースの実装が用意されています。このクラスを使用すると、SQLのようなWHERE句の構文を使用してFilteredRowSetのフィルタを定義できます。「SQLPredicate、SQL方式のRowSetフィルタ」を参照してください。特有のプログラミング上の考慮事項RowSetフィルタは累積的ではないフィルタの設定、変更前に保留中の変更を解決するRowSetフィルタは累積的ではないFilteredRowSetのWebLogic実装では現在、FilteredRowSetにフィルタを2回設定すると古いフィルタが新しいフィルタで置き換えられます。JSR-114にはこの点についてはっきりとした規定がありません。参照実装は同じように動作しません。行セット内のフィルタリングされた行をさらにフィルタリングします。この場合2回目のフィルタを変更して必要なすべての条件をフィルタするようにすると、同じ効果を得られます。フィルタの設定、変更前に保留中の変更を解決するRowSetフィルタを設定または変更する前にRowSetに保留中の変更がある場合、その変更を受け入れる(acceptChanges()を呼び出す)か、RowSetのデータを変更前の状態に戻す(restoreOriginal()を呼び出す)必要があります。Serverでは行われる可能性のある変更を示せるようにRowSet内の移動が認められており、ユーザーはRowSetフィルタを変更する前に上記のどちらかのメソッドを呼び出す必要があります。acceptChanges()ではデータベースへのアクセスが行われ、restoreOriginal()では行われません。SQLPredicateを使用してフィルタを適用および変更する方法について示します。}}FilteredRowSetのクラスとインタフェースのインポート標準のFilteredRowSetを使用するには、次のクラスをインポートする必要があります。javax.sql.rowset.FilteredRowSet;weblogic.jdbc.rowset.RowSetFactory;上記のサンプル・コードでは、フィルタの作成にweblogic.jdbc.rowset.SQLPredicateクラスも使用されています。アプリケーションでは、weblogic.jdbc.rowset.SQLPredicateクラスを使用することも、独自のフィルタ・クラスを作成することも可能です。詳細については「FilteredRowSetに対するフィルタの設定」を参照してください。FilteredRowSetの作成RowSetはファクトリ・インタフェースから作成されます。ServerでFilteredRowSetを作成するには、主に以下の手順に従います。RowSetFactoryインスタンスを作成します。このインスタンスはアプリケーションで使用するRowSetオブジェクトを作成するためのファクトリとして機能します。RowSetFactory.newInstance();WLCachedRowSetを作成してjavax.sql.rowset.FilteredRowSetオブジェクト型にキャストします。RowSetFactoryメソッドでWLCachedRowSetオブジェクトが作成されます。このオブジェクトをそのまま使用することもできますが、標準のFilteredRowSetオブジェクトを使用する場合は、オブジェクトをFilteredRowSetオブジェクトとしてキャストできます。rsfact.newCachedRowSet();FilteredRowSetのプロパティの設定FilteredRowSetのプロパティのオプションはCachedRowSetのオプションと同じです。「CachedRowSetのプロパティの設定」を参照してください。FilteredRowSetのデータベース接続のオプションFilteredRowSetのデータベース接続のオプションはCachedRowSetのオプションと同じです。「データベース接続のオプション」を参照してください。FilteredRowSetへの入力FilteredRowSetのデータ入力のオプションはCachedRowSetのオプションと同じです。「CachedRowSetへの入力」を参照してください。FilteredRowSetのメタデータの設定RowSetのデータ変更をデータベースとの間で同期するために、RowSetにメタデータを設定することが必要な場合もあります。詳細については、「RowSetに対するデータベース更新用メタデータの設定」を参照してください。(フィルタ)オブジェクトをこのメソッドのパラメータとして渡します。Predicateオブジェクトはjavax.sql.rowset.Predicateインタフェースを実装するクラスのインスタンスです。FilteredRowSetのWebLogic実装では、独自のフィルタを定義することも、weblogic.jdbc.rowset.SQLPredicateクラスのインスタンスを使用することもできます。ユーザー定義のRowSetフィルタFilteredRowSet用のフィルタを定義する場合、主に以下の手順に従います。使用するフィルタリング動作(表示する行を特定の列の値を持つ行に制限するなど)を行うjavax.sql.rowset.Predicateインタフェースを実装するクラスを定義します。ID列の値の範囲に基づいて表示される行を制限できます。定義するクラスには、ID列の値をフィルタリングするためのロジックが含まれます。クラスのインスタンス(フィルタ)を作成して、使用するフィルタ条件を指定します。ID列の値が100から199までの行のみを表示するといった指定が可能です。rowset.setFilter()を呼び出して、クラスをこのメソッドのパラメータとして渡します。例8-3に、javax.sql.rowset.Predicateインタフェースを実装するクラスのサンプルを示します。このサンプルでは、列の値の大文字と小文字を区別しないバージョンを評価するフィルタを作成することができるクラスが示されます。例8-4に、フィルタ条件を判断するクラスのインスタンスを作成してから、FilteredRowSet用のフィルタとしてフィルタ・オブジェクトを設定するコードを示します。Serverにはjavax.sql.rowset.Predicateインタフェースを実装するweblogic.jdbc.rowset.SQLPredicateクラスが用意されています。SQLPredicateクラスを使用すると、SQLのようなWHERE句の構文を使用するフィルタを定義してRowSetの行をフィルタできます。103");rs.setFilter(filter);詳細については、「SQLPredicate、SQL方式のRowSetフィルタ」を参照してください。FilteredRowSetのデータの操作FilteredRowSetのデータの操作はCachedRowSetのデータの操作とほぼ同様です。行を挿入したり更新したりする場合には、必ずフィルタ条件の範囲内で変更を行って、操作した行が表示される行の集合に残るようにします。RowSetのフィルタでID列の値が105より小さい行のみを表示できる場合、ID列の値が106の行を挿入しようとしたり、IDの値を106に更新しようとしたりすると、操作は失敗してSQLExceptionがスローされます。データ操作の詳細については、「CachedRowSetのデータの操作」を参照してください。WebRowSetWebRowSetは、RowSetをXMLフォーマットで読み書きできるキャッシュされたRowSetです。WebRowSetには以下のような特性があります。iStream)メソッドを使用してXMLソースからRowSetに入力します。oStream)メソッドを使用してデータおよびメタデータをXMLで書き込み、他のアプリケーション・コンポーネントで使用できるように、またはリモート・クライアントに送信できるようにします。XMLスキーマ定義に準拠します。この定義はhttp://java.sun.com/xml/ns/jdbc/webrowset.xsdで入手できます。(http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/WebRowSet.html)を参照してください。ServerではRowSetについて2つのスキーマがサポートされています。1つは標準WebRowSet用、もう1つはWLCachedRowSet用です。これは、JSR-114の最終仕様より前に実装されたものです。特有のプログラミング上の考慮事項WebLogicのWebRowSet実装では2つのXMLスキーマ(およびAPI)がサポートされます。1つは標準のWebRowSet仕様で(http://java.sun.com/xml/ns/jdbc/webrowset.xsdで入手可能)、もう1つはWLCachedRowSet用です。これは、JSR-114の最終仕様より前に実装されたものです。Server行セットのみを使用している場合、いずれかのスキーマを使用できます。固有スキーマにはより多くの要素タイプがあります。他のRowSetの実装と対話するには、標準のスキーマを使用する必要があります。JOINによって単一のRowSetに結合された、多数の接続されていないRowSetオブジェクトです。JoinRowSetには以下のような特性があります。JoinRowSetに追加される各RowSetには、JoinRowSetへのRowSetの追加に使用されるaddRowSetメソッドで指定された「一致する」列があることが必要です。columnName);setJoinTypeメソッドを使用して、結合タイプを設定できます。以下の結合タイプがサポートされています。これらを使用すると、データベースに接続されていなくてもデータを結合できます。JoinRowSetsは読取り専用。JoinRowSetはデータベースのデータを更新するためには使用できません。JoinRowSetの一致する列は、Number、Boolean、Date、およびStringの4つのデータ型に制限されています。表8-1に、JoinRowSetの一致する列で使用できるデータ型の詳細について示します。(http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/Joinable.html)およびJoinRowSetインタフェース(http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/JoinRowSet.html)のJavadocを参照してください。JDBCRowSetJDBCRowSetはResultSetオブジェクトのラッパーで、これによって結果セットをJavaBeanコンポーネントとして使用できるようになります。JDBCRowSetは、接続されているRowSetです。これ以外の種類のRowSetはすべて接続されていないRowSetです。(http://download.oracle.com/javase/6/docs/api/javax/sql/rowset/JdbcRowSet.html)を参照してください。ServerではRowSetの元のデータ(最後の同期以降のデータ)が、データベースのデータとオプティミスティックな同時実行性ポリシーに基づいて比較されます。データの変更が検出されると、javax.sql.rowset.spi.SyncProviderExceptionがスローされます。デフォルトでは、アプリケーションでは何も行う必要はありませんが、RowSetの変更はデータベースと同期されません。した例外を処理してシステムに適した方法でデータ変更を行うように、アプリケーションを設計できます。注意:javax.sql.rowset.CachedRowSetsについては、RowSetのすべての行にあるすべての元の値が、対応するデータベースの行と比較されます。weblogic.jdbc.rowset.WLCachedRowSet、または他のWebLogic拡張のRowSetでは、オプティミスティックな同時実行性の設定に基づいてデータが比較されます。詳細については、「オプティミスティックな同時実行性ポリシー」を参照してください。SyncProviderExceptionを処理する主な手順は次のとおりです。javax.sql.rowset.spi.SyncProviderExceptionを捕捉します。この例外からSyncResolverオブジェクトを取得します。「SyncResolverオブジェクトの取得」を参照してください。nextConflict()または任意の他の移動用メソッドを使用して、競合まで移動します。「SyncResolverオブジェクト内の移動」を参照してください。(RowSetに値を設定するメソッド)で設定します。「RowSetデータの同期の競合に対する解決後の値の設定」を参照してください。競合している値ごとに、手順3と4を繰り返します。rowset.acceptChanges()を呼び出し、新しい解決後の値を使用してデータベースとの間で変更を同期します。「変更の同期」を参照してください。SyncResolverおよびSyncProviderExceptionの詳細については、RowSetの仕様またはSyncResolverインタフェースのJavadocを参照してください。注意:SyncProviderExceptionの解決を開始する前に、他のどのプロセスもデータを更新することのないようにします。表8-2に、RowSetからデータベースにデータの変更を同期する際に起こる、競合状況の種類について示します。更新RowSetとデータベースの同じ行の値が変更されました。SyncResolverのステータスはSyncResolver.UPDATE_ROW_CONFLICT。場合によりアプリケーションで、この競合を解決するロジックを提供するか、ユーザーに新しいデータを提示することが必要になります。削除RowSetの行の値は更新されたが、データベースではその行が削除されました。SyncResolverのステータスはSyncResolver.UPDATE_ROW_CONFLICT。場合によりアプリケーションで、行を削除されたままにしておく(データベースの状態のようにする)か、行を元に戻してRowSetからの変更を永続化するかを決定するロジックの提供が必要になります。行を削除されたままにするには、RowSetの行の変更を元に戻します。行を元に戻して変更するには、目的の値を持つ新しい行を挿入します。データベースで行が削除されている場合、競合している値がないことに注意します。getConflictValue()を呼び出すと、weblogic.jdbc.rowset.RowNotFoundExceptionがスローされます。更新RowSetの行は削除されたが、データベースではその行が更新されました。SyncResolverのステータスはSyncResolver.DELETE_ROW_CONFLICT。場合によりアプリケーションで、行を削除する(RowSetの状態のようにする)か、行を保持してデータベースでの現在の変更を永続化するかを決定するロジックの提供が必要になります。この場合、行のすべての値が競合した値になります。行を保持してデータベースの現在の値とするには、setResolvedValueを呼び出して、行の各列に解決後の値を設定してデータベースの現在の値にします。削除するには、syncprovider.deleteRow()を呼び出します。削除RowSetで行が削除され、データベースでは別のプロセスでその行が削除されました。SyncresolverのステータスはSyncResolver.DELETE_ROW_CONFLICT。SyncProviderExceptionを解決するには、RowSetのその行に対する削除処理を取り消す必要があります。行のどの列にも、競合している値がない(nullもない)ことに注意します。getConflictValue()を呼び出すと、weblogic.jdbc.rowset.RowNotFoundExceptionがスローされます。挿入RowSetに行が挿入され、データベースにも別の行が挿入された場合、主キーの競合が起こることがあります。その場合SQL例外がスローされます。SyncProviderExceptionはスローされないので、この種類の競合をSyncResolverを使って直接的に処理することはできません。SyncResolverのサンプル・コード例8-5に、RowSetとデータベースの間で競合している値をSyncResolverを使って解決する方法についての要約されたサンプルを示します。このサンプルでは、競合のあるSyncResolverの各行について、認識されている名前を持つ列の値をチェックします。このサンプルの詳細については、サンプルの後の節で説明します。}}SyncResolverオブジェクトの取得SyncProviderExceptionを処理するために、例外を捕捉してそこからSyncResolverオブジェクトを取得できます。.}SyncResolverは、SyncResolverインタフェースを実装するRowSetです。SyncResolverオブジェクトには、元のRowSetのすべての行に対応する行が含まれます。競合していない値については、SyncResolverでの値はnullになります。競合している値については、データベースの現在の値が値として格納されます。SyncResolverオブジェクト内の移動SyncResolverオブジェクトを使用すると、すべての競合に移動して、競合している各値に適切な値を設定できます。SyncResolverインタフェースにはnextConflict()メソッドとpreviousConflict()メソッドが含まれており、これらを使用してnull以外の競合している値を持つSyncResolver内で、直接次の行に移動できます。SyncResolverオブジェクトはRowSetなので、SyncResolverの任意の行へのカーソル移動には、すべてのRowSet移動用メソッドも使用できます。nextConflict()メソッドおよびpreviousConflict()メソッドを使用すると、競合している値のない行を簡単にスキップできます。競合している行にカーソルを移動した後には、各列の値をgetConflictValue()メソッドでチェックして、RowSet内の値と競合しているデータベース内の値を検索してから、それらの値を比較して競合の処理方法を決定する必要があります。値が競合していない行の場合、戻り値としてnullが返されます。行がデータベースでは削除されていた場合、戻り値はなく、例外がスローされます。注意:WebLogicのRowSet実装では、データベースの行の任意の値と、RowSetの作成時または最後の同期時にRowSetに読み込まれた値が異なる場合、値の競合が発生します。RowSetとデータベースの値を比較するコードのサンプルを以下に示します。RowSetデータの同期の競合に対する解決後の値の設定データベースに永続化するための適切な値を設定するには、setResolvedValue()を呼び出します。resolvedValue);setResolvedValue()メソッドでは以下の変更が行われます。データベースに永続化するための値を設定します。RowSetの現在の値を設定します。変更が同期されると、この新しい値がデータベースに永続化されます。RowSetのデータの元の値をデータベースの現在の値に変更します。元の値とは、最後の同期以降に設定されていた値です。setResolvedValue()を呼び出すと、元の値がデータベースの現在の値になります。同期の呼出しにおけるWHERE句を、データベースの適切な行が更新されるように変更します。変更の同期SyncResolverで競合している値を解決した後には、変更をデータベースとの間で同期する必要があります。これを行うには、rowset.acceptChanges()をもう一度呼び出します。acceptChanges()呼出しではSyncResolverオブジェクトがクローズされ、同期の完了後にデータベースのロックが解放されます。WLCachedRowSetWLCachedRowSetはCachedRowSets、FilteredRowSets、WebRowSets、およびSortedRowSetsの拡張です。WLCachedRowSetには以下のような特性があります。ServerのRowSet実装では、すべてのRowSetが元はWLCachedRowsetとして作成されます。WLCachedRowSetは、それを拡張するあらゆる標準RowSet型として互換的に使用できます。WLCachedRowSetには、RowSetをより簡単に扱えるようにする便利なメソッド群があり、またオプティミスティックな同時実行性オプションとデータ同期化オプションを設定するメソッド群も含まれています。SQLXMLデータ型オブジェクトを読み取ったり更新したりすることはできない場合があります。4.0仕様では、ベンダーがSQLXMLオブジェクトを設定後にこれを読取り可能にする必要はないとしています。ServerがSQLXMLデータ型オブジェクトに値を設定したら、このオブジェクトを読み取ったり更新したりできなくなります。詳細については、weblogic.jdbc.rowset.WLCachedRowSetインタフェースのJavadocを参照してください。SharedRowSetRowSetは1つのスレッドでのみ使用できます。複数のスレッドで共有することはできません。SharedRowSetはCachedRowSetを拡張したもので、元のCachedRowSetのデータに基づいて、他のスレッドで使用するCachedRowSetを追加作成できます。SharedRowSetには以下のような特性があります。各SharedRowSetは、元のRowSetの表層的なコピー(データのコピーではなく、元のRowSetのデータへの参照)で、独自のコンテキスト(カーソル、フィルタ、ソーター、保留中の変更、および同期プロバイダ)を備えています。任意のSharedRowSetで行われたデータの変更がデータベースとの間で同期されると、基底のCachedRowSetも更新されます。SharedRowSetを使用すると、アプリケーションで必要とするデータベースへの往復回数が減るため、パフォーマンスが向上する可能性があります。SharedRowSetを作成するには、WLCachedRowSetインタフェースのcreateShared()メソッドを使用して、その結果をWLCachedRowSet型にキャストします。(WLCachedRowSet)rowset.createShared();SortedRowSetSortedRowSetはCachedRowSetを拡張して、CachedRowSetの行をアプリケーションで提供されるComparatorオブジェクトに基づいてソートできるようにしたものです。SortedRowSetには以下のような特性があります。ソート処理の設定方法は、FilteredRowSetでのフィルタ処理の設定方法と同様。ソート処理はjavax.sql.rowset.Predicateオブジェクトではなくjava.util.Comparatorオブジェクトに基づきます。アプリケーションで、目的のソート動作を行うComparatorオブジェクトを作成します。続いてアプリケーションでsetSorter(java.util.Comparator)メソッドを使用してソート条件を設定します。ソート処理はメモリー内で行われ、データベース管理システムには依存しません。SortedRowSetを使用することによりデータベースへの往復回数が減るため、アプリケーションのパフォーマンスが向上する可能性があります。Serverにはjava.util.Comparatorを実装するSQLComparatorオブジェクトが用意されています。これを使用して、ソート条件として使う列のリストを渡すことで、SortedRowSetの行をソートできます。weblogic.jdbc.rowset.SQLComparator("columnA,columnB,columnC"));詳細については、Javadocsで以下について参照してください。weblogic.jdbc.rowset.SortedRowSetインタフェースweblogic.jdbc.rowset.SQLComparatorクラスSQLPredicate、SQL方式のRowSetフィルタここでは、SQLPredicateクラスについて説明します。Serverにはjavax.sql.rowset.Predicateインタフェースの実装であるweblogic.jdbc.rowset.SQLPredicateクラスが用意されています。SQLPredicateクラスを使用すると、SQLのようなWHERE句の構文を使用してFilteredRowSetのフィルタを定義できます。SELECT文のWHERE句の文法とよく似ています。重要な注意事項を以下に示します。列を参照する場合、列名を使用する必要があります。列の索引番号は使用できません。この文法では、演算子および数学演算がサポートされます。次のようなことができます。>=100.WHERE句の作成では、単純なデータ型のみを使用できます。以下のようなデータ型を使用できます。StringIntBooleanFloat以下のような複合データ型はサポートされません。103");rs.setFilter(filter);詳細については、weblogic.jdbc.rowset.SQLPredicateクラスのJavadocを参照してください。オプティミスティックな同時実行性ポリシーほとんどの場合、RowSetへのデータの入力とデータベースの更新は別々のトランザクションで発生します。データベース内の基底のデータは2つのトランザクションの間に変更される可能性があります。ServerのRowSet実装(WLCachedRowSet)では、オプティミスティックな同時実行性制御を使用して、データベースの一貫性を確保します。オプティミスティックな同時実行性の場合、RowSetは複数のユーザーが同じデータを同時に変更する可能性は低いという前提で動作します。そのため、接続されていないRowSetモデルの一端として、RowSetではデータベース・リソースがロックされません。データベースに変更を書き込む前に、データベース内の変更予定のデータが、そのデータがRowSetに読み込まれたときから変更されていないことをRowSetでチェックする必要があります。RowSetから発行されるUPDATE文とDELETE文には、データベース内のデータを、RowSetの入力時に読み込まれたデータに照らして検証するためのWHERE句が含まれます。RowSetではデータベース内の基底のデータが変更されたことが検出されるとOptimisticConflictExceptionが発行されます。アプリケーションではこの例外を捕捉して処理方法を決定できます。一般的には、アプリケーションで、変更されたデータをリフレッシュしてユーザーに再度提示します。WLCachedRowSet実装には複数のオプティミスティックな同時実行性ポリシーが用意されています。これらのポリシーによって、基底のデータベースのデータを検証するためにRowSetから発行されるSQLが決まります。VERIFY_READ_COLUMNSVERIFY_MODIFIED_COLUMNSVERIFY_SELECTED_COLUMNSVERIFY_NONEVERIFY_AUTO_VERSION_COLUMNSVERIFY_VERSION_COLUMNSこれらのポリシーの違いを例示するために、以下のような内容の例を使用します。Smithの給与が20000に設定されます。続いて、オプティミスティックな同時実行性ポリシーがRowSetから発行されるSQLコードにどのように影響するかが示されます。VERIFY_READ_COLUMNSデフォルトでは、RowSetのオプティミスティックな同時実行性制御ポリシーはVERIFY_READ_COLUMNSです。RowSetからUPDATEまたはDELETEが発行されるときに、データベースから読み込まれたすべての列がWHERE句に含まれます。これによって、RowSetに最初に読み込まれたすべての列の値について変更されてないかどうかが検証されます。この例では、RowSetから次のように発行されます。Smith';VERIFY_MODIFIED_COLUMNSVERIFY_MODIFIED_COLUMNSポリシーでは、主キー列と更新される列のみがWHERE句に含まれます。アプリケーションで更新される列の一貫性だけを考慮する場合に便利です。データを読み込んだ後に更新の対象外の列が変更されていても、この更新をコミットできます。この例では、RowSetから次のように発行されます。e_id列は主キー列なので含まれています。e_salary列は更新される列なので、同様に含まれています。e_name列は読み込まれただけなので、検証されません。VERIFY_SELECTED_COLUMNSVERIFY_SELECTED_COLUMNSでは、主キー列と指定する列がWHERE句に含まれます。true);metaData.acceptChanges();この例では、RowSetから次のように発行されます。e_id列は主キー列なので含まれています。e_salary列は選択された列なので、同様に含まれています。VERIFY_NONEVERIFY_NONEポリシーでは、主キー列のみがWHERE句に含まれます。データベース・データに対して追加で検証は行われません。この例では、RowSetから次のように発行されます。1VERIFY_AUTO_VERSION_COLUMNSVERIFY_AUTO_VERSION_COLUMNSでは、主キー列と、別個のバージョン列がWHERE句に含まれます。RowSetでは更新の一環としてバージョン列の自動的なインクリメントも行われます。このバージョン列のデータ型はintegerでなければなりません。データベース・スキーマを更新して、別個のバージョン列(e_version)を含める必要があります。例では、この列の現在の値が1であると仮定します。true);metaData.acceptChanges();この例では、RowSetから次のように発行されます。1e_version列はSET句で自動的にインクリメントされます。WHERE句は主キー列とバージョン列を検証しています。VERIFY_VERSION_COLUMNSVERIFY_VERSION_COLUMNSの場合、RowSetでは主キー列と、別個のバージョン列がチェックされます。RowSetでは更新の一環としてバージョン列はインクリメントされません。データベース・スキーマを更新して、別個のバージョン列(e_version)を含める必要があります。例では、この列の現在の値が1であると仮定します。true);metaData.acceptChanges();この例では、RowSetから次のように発行されます。1WHERE句では主キー列とバージョン列が検証されます。RowSetでバージョン列がインクリメントされないため、この処理はデータベースで行う必要があります。一部のデータベースでは、行の更新時に自動的にインクリメントするバージョン列を提供しています。データベース・トリガーを使用してこのタイプの更新を処理することもできます。オプティミスティックな同時実行性制御の制限オプティミスティックなポリシーでは、変更する行に対するUPDATE文とDELETE文のみが検証されます。読取り専用の行はデータベースに照らして検証されません。ほとんどのデータベースではWHERE句でのBLOBまたはCLOB列の使用が許可されていないため、RowSetではBLOBまたはCLOB列の検証はできません。RowSetに複数の表が含まれる場合、RowSetでは更新された表のみが検証されます。オプティミスティックなポリシーの選択デフォルトのVERIFY_READ_COLUMNSでは、パフォーマンスを多少犠牲にして、強力なレベルの一貫性が提供されます。最初に読み込まれたすべての列をデータベースに送信したり、データベースと比較したりする必要があるため、このポリシーでは多少のオーバーヘッドが追加で発生します。VERIFY_READ_COLUMNSは強力なレベルの一貫性が必要な場合に適しています。バージョン列を含めるようにデータベース表を変更することはできません。VERIFY_SELECTED_COLUMNSは、開発者が検証を完全に制御する必要があり、アプリケーションに固有の知識を使用してSQLを微調整する場合に便利です。VERIFY_AUTO_VERSION_COLUMNSでは、VERIFY_READ_COLUMNSと同じレベルの一貫性が提供されますが、integer型の1つの列を比較するだけで済みます。このポリシーではバージョン列のインクリメントも行われるため、データベースの設定が若干必要です。VERIFY_VERSION_COLUMNSは、最高レベルのパフォーマンスと一貫性が必要な本番システムにお薦めします。VERIFY_AUTO_VERSION_COLUMNSと同様に、高いレベルの一貫性が提供されますが、データベースで1つの列の比較が行われるだけです。VERIFY_VERSION_COLUMNSでは、データベースでバージョン列のインクリメントを行う必要があります。一部のデータベースでは、更新時に自動的にインクリメントする列タイプを提供していますが、この動作はデータベース・トリガーを使用して実装することもできます。VERIFY_MODIFIED_COLUMNSとVERIFY_NONEでは一貫性が確保される程度は低下しますが、オプティミスティックな競合が起きる可能性も少なくなります。高レベルなデータの一貫性の必要性よりも、パフォーマンス、競合の回避の方が重要な場合は、これらのポリシーを検討します。パフォーマンスのオプションRowSetを使用する場合は以下のパフォーマンス・オプションを検討します。JDBCのバッチ処理RowSet実装ではJDBCのバッチ処理もサポートされています。各SQL文をJDBCドライバに個々に送信する代わりに、バッチ処理では文の集合を1つの一括処理としてJDBCドライバに送信します。バッチ処理はデフォルトで無効になっていますが、一般に1つのトランザクションで多数の更新が発生する場合にパフォーマンスが向上します。アプリケーションとデータベースに対してこのオプションを有効および無効に設定して、ベンチマークを実行してみるとよいでしょう。WLCachedRowSetインタフェースには、INSERT、DELETE、およびUPDATE文のバッチ処理を制御するためのsetBatchInserts(boolean)、setBatchDeletes(boolean)、およびsetBatchUpdates(boolean)メソッドがあります。注意:setBatchInserts、setBatchDeletes、setBatchUpdatesメソッドは、acceptChangesメソッドを呼び出す前に呼び出す必要があります。Databaseのバッチ処理の制限WLCachedRowSetはオプティミスティックな同時実行性制御に依存しているため、更新または削除コマンドが成功したか、オプティミスティックな競合が発生したかを判別する必要があります。WLCachedRowSet実装では、文によって更新された行の数についてのJDBCドライバの報告に基づいて、競合が発生したかどうかを判別します。更新された行が0の場合、WLCachedRowSetでは競合が発生したと認識されます。JDBCドライバではバッチ更新が実行されるとjava.sql.Statement.SUCCESS_NO_INFOが返されるため、RowSet実装では競合が発生したかどうかを判別するために戻り値を使用できません。バッチ処理がOracleデータベースで使用されることがRowSetで検出された場合、バッチ処理の動作は自動的に変更されます。バッチ挿入は検証されないため、通常どおり実行されます。バッチ更新は正常に実行されますが、RowSetでは特別なSELECT問合せが発行され、バッチ更新でオプティミスティックな競合が発生したかどうかがチェックされます。SELECT検証問合せの後でバッチ削除を実行するよりも効率的なため、バッチ削除ではグループ削除が使用されます。複数の行を削除する場合、RowSetでは通常、削除する行ごとにDELETE文が発行されます。グループ削除を有効にした場合、RowSetでは削除する行を含むWHERE句が指定されたDELETE文が1つだけ発行されます。表から3人の従業員を削除する場合、通常であればRowSetから次のように発行されます。10;グループ削除を有効にした場合、RowSetから次のように発行されます。10;WLRowSetMetaData.setGroupDeleteSizeを使用すると、1つのDELETE文に含まれる行の数を決定できます。デフォルト値は50です。reserved.法律上の注意点ライブラリ。