モジュール java.sql.rowset

パッケージ javax.sql.rowset.spi

サード・パーティ・ベンダーが同期プロバイダの実装で使用する必要がある標準クラスおよびインタフェースです。 これらのクラスおよびインタフェースをまとめて、「サービス・プロバイダ・インタフェース(Service Provider Interface、SPI)」と呼びます。 RowSetオブジェクトで実装を使用できるようにするには、その実装をSyncFactoryシングルトンに登録する必要があります。 登録手順と命名規則の詳しい説明については、SyncProviderのクラス・コメントを参照してください。

目次

1.0 パッケージの仕様

javax.sql.rowset.spiパッケージは、次のクラスおよびインタフェースで構成されています。

  • SyncFactory
  • SyncProvider
  • SyncFactoryException
  • SyncProviderException
  • SyncResolver
  • XmlReader
  • XmlWriter
  • TransactionalWriter
このSPIには、javax.sqlパッケージ内の次のインタフェースも含まれています。
  • RowSetReader
  • RowSetWriter

SyncProvider実装は、未接続のRowSetオブジェクトがデータを読み込み、変更を加えたあと配下のデータ・ソースに再度書き込めるようにするメカニズムを提供します。 リーダー・オブジェクト(RowSetReaderまたはXMLReader)は、CachedRowSetexecuteまたはpopulateメソッドが呼び出されると、RowSetオブジェクトにデータを読み込みます。 ライター・オブジェクト(RowSetWriterまたはXMLWriter)は、CachedRowSetacceptChangesメソッドが呼び出されると、配下のデータ・ソースに変更されたデータを書き込みます。

RowSetオブジェクトの変更内容をデータ・ソースに書き込む処理を同期と呼びます。 RowSetオブジェクトのライターが使用する同期のレベルは、RowSetオブジェクトのSyncProvider実装によって決定されます。 同期のさまざまなレベルのことをグレードと呼びます。

低グレードの同期は、競合がまったく存在しないか、存在したとしてもわずかであるというオプティミスティック(楽観的)な想定のもとに行われます。この同期モデルをオプティミスティック並行モデルと呼びます。 RowSetオブジェクト内で変更されたデータがデータ・ソース内でも変更されている場合は、競合が存在します。 オプティミスティック並行モデルを使用するということは、競合が存在する場合、データ・ソースまたはRowSetオブジェクトへの変更が失われるということを意味します。

これに対して、高グレードの同期モデルをペシミスティック(悲観的)並行モデルと呼びます。このモデルでは、他のユーザーがデータ・ソースにアクセスして変更を加える可能性があるという想定のもとに同期処理が行われます。 ペシミスティック並行モデルでは、競合の発生を抑えるため、様々なロック・レベルが設定されます。

最低レベルの同期では、RowSetオブジェクトへの全変更内容が、単純に配下のデータ・ソースに書き込まれます。 ライターは競合のチェックを行いません。 競合が存在し、データ・ソースの値が上書きされた場合、その他のユーザーによるデータ・ソースの変更は失われます。

RIXMLProvider実装は、最低レベルの同期を使用し、RowSetの変更を単純にデータ・ソースに書き込みます。

次のレベル・アップのために、ライターは競合がないかどうかをチェックし、競合があれば、データソースに何も書き込みません。 この同期レベルには、RowSetオブジェクトがデータを取得したあと別のユーザーがデータ・ソース内の対応するデータに変更を加えた場合、RowSetオブジェクトの変更が失われるという問題があります。 RIOptimisticProvider実装は、この同期レベルを使用します。

最高レベルの同期(ペシミスティック並行モデルの同期)では、ライターは、競合を避けるためにロックを設定します。 ロックの設定といっても、単一の行のロックから、テーブルまたはデータ・ソース全体のロックまで、さまざまなレベルがあります。 したがって、同期レベルは、複数のユーザーによるデータ・ソースへの並行アクセスに重点を置くかと、ライターがRowSetオブジェクト内のデータとデータ・ソースを同期させておくことに重点を置くかとのトレードオフになります。

反対に、ライターの機能を有効にすれば、同時アクセス機能は無効になります。未接続のすべてのRowSetオブジェクト(CachedRowSetFilteredRowSetJoinRowSet、およびWebRowSetオブジェクト)は、SyncFactoryメカニズムからSyncProviderオブジェクトを取得する必要があります。

リファレンス実装(RI)は、次の2つの同期プロバイダを提供します。

  • RIOptimisticProvider
    プロバイダ実装が指定されていないとき、SyncFactoryインスタンスから未接続のRowSetオブジェクトに提供されるデフォルトのプロバイダ。

    この同期プロバイダは、データベース内の同じデータにアクセスするユーザー間に競合がほとんど存在しないと想定した、オプティミスティック並行モデルを使用します。
    ロックは使用しませんが、その代わりに、RowSetオブジェクトとデータ・ソースの同期をとる前に、競合が存在するかどうかのチェックを行います。 競合が存在する場合は、何も行いません。つまり、RowSetオブジェクトの変更は、データ・ソースでは保持されません。
  • RIXMLProvider
    WebRowSetオブジェクト、すなわちXML形式で読み取りまたは書込み可能な行セットで使用できる同期プロバイダ。
    RIXMLProvider実装は競合のチェックを一切行わず、WebRowSetオブジェクトの更新データを配下のデータ・ソースに単純に書き込みます。 WebRowSetオブジェクトは、XMLデータの処理時に、このプロバイダを使用します。
これらのSyncProvider実装は、リファレンス実装にバンドルされているため、RowSet実装はこれらの実装をいつでも利用できます。 SyncProvider実装は、SyncFactoryシングルトンに登録されると、利用可能な状態になります。 RowSetオブジェクトからプロバイダ(コンストラクタ内に指定、またはCachedRowSetsetSyncProviderメソッドの引数として指定)の要求を受け取ると、SyncFactoryシングルトンは、要求されたプロバイダが登録されているかどうかを確認します。 登録されている場合は、SyncFactoryはそのインスタンスを作成し、要求元のRowSetオブジェクトに渡します。 指定されたSyncProvider実装が登録されていない場合は、SyncFactoryシングルトンはSyncFactoryExceptionオブジェクトをスローします。 プロバイダが指定されていない場合は、SyncFactoryはデフォルト・プロバイダ実装RIOptimisticProviderを作成し、要求元のRowSetオブジェクトに渡します。

WebRowSetオブジェクトのコンストラクタ内にプロバイダが指定されていない場合、SyncFactoryは、RIOptimisticProviderのインスタンスを渡します。 ただし、実装により、WebRowSetのコンストラクタがプロバイダとしてRIXMLProviderを設定する場合、RowSetオブジェクトの読み取りおよび書込みはXML形式で行われます。

詳細については、SyncProviderクラス仕様を参照してください。

ベンダーは、SyncProvider実装と任意の同期レベルを開発し、RowSetオブジェクトに同期メカニズムを選択させることができます。

2.0 サービス・プロバイダ・インタフェース・アーキテクチャ

2.1 概要

サービス・プロバイダ・インタフェースは、SyncProvider実装を登録したあと、必要なときに生成することができる、プラグイン可能なメカニズムを提供します。 SyncFactoryの遅延参照メカニズムは、未接続のRowSetオブジェクトから要求があるまでインスタンスの生成を遅らせることにより、リソースの無駄な消費を制限します。 SyncFactoryクラスは、特定のSyncProvider実装によって提供可能なロギング・オプションとストリームを構成するための標準APIも提供します。

2.2 SyncFactoryへの登録

未接続のRowSetオブジェクトがサード・パーティのSyncProvider実装を取得し、そのjavax.sql.RowSetReader実装とjavax.sql.RowSetWriter実装を使用できるようにするには、この実装をSyncFactoryに登録する必要があります。 すべてのSyncProvider実装は、次の登録メカニズムを利用できます。

  • システム・プロパティ - コマンド行で設定するプロパティ。 これらのプロパティは実行時に設定され、Javaアプリケーションの呼出しによってシステム全体に適用される。 詳細については、「関連項目」を参照。
  • プロパティ・ファイル - 標準プロパティ・ファイルに指定するプロパティ。 システム・プロパティを利用するか、プラットフォームの実行時に検出された標準プロパティ・ファイルを変更することによって指定する。 このテクノロジのリファレンス実装には標準プロパティ・ファイルが1つ含まれる。この標準プロパティ・ファイルを編集することで、SyncProviderオブジェクトを追加できる。
  • JNDIコンテキスト - 使用可能なプロバイダはJNDIコンテキストに登録できる。 SyncFactoryは、コンテキストにバインドされたSyncProviderオブジェクトをロードし、ファクトリに登録しようとする。 このメカニズムを正常に機能させるためには、コンテキストをSyncFactoryに渡す必要がある。

プロパティ・ファイル内にシステム・プロパティやプロパティを指定する方法、JNDIコンテキストを構成する方法の詳細については、SyncFactoryクラスの説明を参照してください。

2.3 SyncFactoryプロバイダ・インスタンス生成ポリシー

プロバイダが正常に登録されていれば、SyncFactoryは要求されたSyncProviderオブジェクトを生成します。 未接続のRowSetオブジェクトが特定のSyncProvider実装で初期化されたとき、またはその他のSyncProviderオブジェクトで実行時に再構成されたときは、次のポリシーが施行されます。

  • SyncProviderオブジェクトが指定され、SyncFactoryにプロバイダの参照が含まれない場合、SyncFactoryExceptionがスローされる。
  • SyncProviderオブジェクトが指定され、SyncFactoryにプロバイダの参照が含まれる場合、要求されたプロバイダが提供される。
  • SyncProviderオブジェクトが指定されていない場合、リファレンス実装プロバイダRIOptimisticProviderが提供される。

これらのポリシーの詳細については、SyncFactoryクラスの説明を参照してください。

3.0 SyncProvider実装者ガイド

3.1 要件

SyncFactoryに完全にプラグイン可能なSyncProvider準拠実装は、すべての抽象メソッドを拡張し、SyncProviderクラスに実装する必要があります 個々の実装は、SyncProviderクラス定義内のグレード、ロック、更新可能ビューの機能を確定する必要があります 1つ以上のSyncProvider記述基準がサポートされている必要があります ベンダー実装は、グレード、ロック、更新可能ビューの機能の範囲を示すことを求められます。

さらに、SyncProvider命名規則に準拠する必要があります。この命名規則の詳細については、SyncProviderクラスの説明を参照してください。

3.2 グレード

JSR 114には、SyncProviderオブジェクトから未接続のRowSetオブジェクトに提供される同期の品質を示す、一連のグレードが定義されています。 これらのグレードは、サービス品質の低い順に一覧されます。

  • GRADE_NONE - もともとのデータ・ソースとの同期は行われない。 このグレードを返すSyncProvider実装は、RowSetオブジェクト内の変更済みデータを配下のデータ・ソースに上書きするのみ。 元の値と現在の値を比較して競合があるかどうかを確認する処理は行われない。 RIXMLProviderは、このグレードで実装されている。
  • GRADE_CHECK_MODIFIED_AT_COMMIT - 低グレードのオプティミスティック並行同期。 このグレードを返すSyncProvider実装は、前回の同期から今回の同期までに変更された行内に競合がないかチェックを行う。 もともとのデータ・ソースに変更が加えられたあと、その内容が未接続のRowSetオブジェクトに反映されることはない。 競合が存在しない場合、RowSetオブジェクト内の変更はデータ・ソースに書き込まれる。 競合が存在する場合、変更内容は書き込まれない。 RIOptimisticProvider実装は、このグレードを使用する。
  • GRADE_CHECK_ALL_AT_COMMIT - 高グレードのオプティミスティック並行同期。 このグレードを返すSyncProvider実装は、未接続のRowSetオブジェクト内のすべての行を、未変更のものも含めてチェックする。 これにより、同期が正常に完了したとき、配下のデータ・ソース内のすべての行の変更が未接続のRowSetオブジェクトに反映される。
  • GRADE_LOCK_WHEN_MODIFIED - ペシミスティック並行同期。 このグレードを返すSyncProvider実装は、RowSetオブジェクト内の行が変更されたとき、データ・ソース内の同じデータが別のプロセスによって変更されることがないように、もともとのデータ・ソース内の行をロックする。
  • GRADE_LOCK_WHEN_LOADED - 高グレードのペシミスティック並行同期。 このグレードを返すSyncProvider実装は、RowSetオブジェクトの移植に使用された元のクエリーの影響を受けるビューとテーブル全体、またはそのいずれかをロックする。

3.3 ロック

JSR 114には、RowSetオブジェクトの配下のデータ・ソースにロックが適用されているかどうか、適用されている場合はどの構造体に適用されているかを示す定数のセットが定義されています。 これらのロックは、データ・ソースからRowSetオブジェクトが切断されるまで、データ・ソース上に保持されます。

これらの定数は、グレード定数を補完する定数であるとみなすべきです。 ほとんどのグレードのデフォルト設定は、RowSetオブジェクトをデータ・ソースから切断するときデータ・ソースのロックも破棄することを要求します。 グレードGRADE_LOCK_WHEN_MODIFIEDおよびGRADE_LOCK_WHEN_LOADEDでは、未接続のRowSetオブジェクトでロックの段階を細かく制御できます。

  • DATASOURCE_NO_LOCK - ロックはもともとのデータ・ソース上に保持されない。 RowSetオブジェクトの管理下にあるものを除くすべてのSyncProvider実装のデフォルトのロック設定です。
  • DATASOURCE_ROW_LOCK - ロックは、RowSetオブジェクトの移植に使用された元のSQLクエリーの影響を受ける行にのみ保持される。
  • DATASOURCE_TABLE_LOCK - ロックは、RowSetオブジェクトの移植に使用されたクエリーの影響を受けるすべてのテーブル上で保持される。
  • DATASOURCE_DB_LOCK - ロックは、RowSetオブジェクトによって使用されるデータ・ソース全体で保持される。

3.4 更新可能ビュー

RowSetオブジェクトには、SQL VIEWのデータを移植できます。 次に、SyncProviderオブジェクトが、VIEWの派生元のテーブル(複数可)内のデータを更新できるかどうかを示す定数を示します。

  • UPDATABLE_VIEW_SYNC SyncProvider実装は、RowSetオブジェクトを生成するために使用されるSQL VIEWが導出される1つ以上の表への同期をサポートすることを示します。
  • NONUPDATABLE_VIEW_SYNC - SyncProvider実装が、RowSetオブジェクトを移植するために使用されたSQL VIEWの派生元のテーブル(複数可)への同期をサポートしないことを示す。

3.5 SyncProviderのグレード機能とロック機能の使用方法

次に、リファレンス実装CachedRowSetImplsetSyncProviderメソッドを呼び出すことによって現在のSyncProviderオブジェクトを再構成する例を示します。

   CachedRowSetImpl crs = new CachedRowSetImpl();
   crs.setSyncProvider("com.foo.bar.HASyncProvider");
 
アプリケーションは、未接続のRowSetオブジェクトによって現在使用されているSyncProviderオブジェクトを取得できます。 また、プロバイダの実装に使用された同期のグレードと現在使用されているロックの段階も取得できます。 アプリケーションの柔軟性を利用して、使用するロックの段階を設定することにより、同期の成功の確率を高めることができます。 これらのオペレーションについては、次のコードの抜粋を参照してください。
   SyncProvider sync = crs.getSyncProvider();

   switch (sync.getProviderGrade()) {
   case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
         //A high grade of optimistic synchronization
    break;
    case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT
         //A low grade of optimistic synchronization
    break;
    case: SyncProvider.GRADE_LOCK_WHEN_LOADED
         // A pessimistic synchronization grade
    break;
    case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED
         // A pessimistic synchronization grade
    break;
    case: SyncProvider.GRADE_NONE
      // No synchronization with the originating data source provided
    break;
    }

    switch (sync.getDataSourceLock() {
      case: SyncProvider.DATASOURCE_DB_LOCK
       // A lock is placed on the entire datasource that is used by the
       // RowSet object
       break;

      case: SyncProvider.DATASOURCE_NO_LOCK
       // No locks remain on the  originating data source.
      break;

      case: SyncProvider.DATASOURCE_ROW_LOCK
       // A lock is placed on the rows that are  touched by the original
       // SQL statement used to populate
       // the RowSet object that is using the SyncProvider
       break;

      case: DATASOURCE_TABLE_LOCK
       // A lock is placed on  all tables that are touched by the original
       // SQL statement used to populated
       // the RowSet object that is using the SyncProvider
      break;

 
SyncFactoryクラスのstaticユーティリティ・メソッドを使って、現在SyncFactoryに登録されているSyncProvider実装の一覧を確認することもできます。
       Enumeration e = SyncFactory.getRegisteredProviders();
 

4.0 同期競合の解決

アプリケーションは、SyncResolverインタフェースを利用して、競合が発生したときの手動での対処法を決定できます。 CachedRowSetacceptChangesメソッドが終了し、競合の存在が確認された場合、このメソッドはSyncProviderExceptionオブジェクトをスローします。 アプリケーションは例外をキャッチし、SyncProviderException.getSyncResolver()メソッド呼出しによってSyncResolverオブジェクトを取得させることができます。

SyncResolverオブジェクトは、SyncResolverインタフェースを実装している特殊なCachedRowSetまたはJdbcRowSetオブジェクトであり、1行ずつ競合のチェックを行います。 同期されるRowSetオブジェクトの複製になっていて、競合の原因となっているデータ・ソースのデータのみを格納しています。 その他のすべての列値はnullに設定されます。 SyncResolverオブジェクトは、競合している値から別の競合している値へ移動できるメソッド、nextConflictおよびpreviousConflictを提供しています。

SyncResolverインタフェースは、次の処理を行うメソッドも提供します。

  • 更新、削除、または挿入を必要とする競合であるかどうかを検出
  • 競合の原因になったデータ・ソース内の値を取得
  • もしデータ・ソース内のデータを変更する必要がある場合その適切な値の設定。もしくは、RowSetオブジェクトのデータを変更する必要がある場合その適切な値の設定

CachedRowSetacceptChanges iメソッドは、呼び出されると、RowSetオブジェクトのSyncProviderオブジェクトを委譲します。 このSyncProviderオブジェクトから提供されるライターの実装方法によって、競合のチェック・レベル(グレード)が決定されます。 競合のチェックがすべて完了し、実際に競合が検出された場合、acceptChangesメソッドはSyncProviderExceptionオブジェクトをスローします。 アプリケーションは例外をキャッチし、この例外を使ってSyncResolverオブジェクトを取得することができます。

その後、SyncResolverメソッドを使って、各競合の情報を取得し、対処方法を決定します。 アプリケーション・ロジックまたはユーザーにより、RowSetオブジェクト内の値を持続させる必要があるという判断が下された場合、アプリケーションまたはユーザーは、この値でデータ・ソース値を上書きできます。

詳細については、SyncResolverインタフェースのコメントを参照してください。

5.0 関連仕様

6.0 関連項目

  • インタフェースのサマリー 
    インタフェース 説明
    SyncResolver
    アプリケーションが、手動の意志決定ツリーを使って同期競合が発生したときの対処方法を決定できるようにするフレームワークを定義します。
    TransactionalWriter
    より精密なトランザクション制御ができるように、標準SyncProvider abstractクラスの拡張を促進する特別なインタフェースです。
    XmlReader
    SyncProvider抽象クラスの拡張を促進する、XML指向の同期プロバイダ向けの特別なインタフェースです。
    XmlWriter
    SyncProvider抽象クラスの拡張を促進する、XML指向の同期プロバイダ向けの特別なインタフェースです。
  • クラスのサマリー 
    クラス 説明
    SyncFactory
    未接続のRowSetオブジェクトによって使用されるSyncProviderインスタンスを生成するサービス・プロバイダ・インタフェース(Service Provider Interface、SPI)メカニズムです。
    SyncProvider
    未接続のRowSetオブジェクトの読み取り/書込み機能を提供する同期メカニズムです。
  • 例外のサマリー 
    例外 説明
    SyncFactoryException
    SyncFactoryメカニズムのエラーを示します。
    SyncProviderException
    SyncProviderメカニズムで発生したエラーを示します。