Java™ Platform
Standard Edition 7

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

サードパーティーベンダーが同期プロバイダの実装で使用する必要がある標準クラスおよびインタフェースです。

参照: 説明

パッケージ javax.sql.rowset.spi の説明

サードパーティーベンダーが同期プロバイダの実装で使用する必要がある標準クラスおよびインタフェースです。これらのクラスおよびインタフェースをまとめて、「サービスプロバイダインタフェース (Service Provider Interface、SPI)」と呼びます。使用可能な SyncProvider 実装の一覧が記載された JDBC Web ページにベンダー固有の実装を追加して、開発者に実装を公開したい場合は、jdbc@sun.com まで電子メールにてご連絡ください。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 の変更を単純にデータソースに書き込みます。これは、通常、XML データソースが、データの整合性を確保するためのトランザクション技術をサポートしていないからです。しかし、XML ベースの同期を可能にする手段を提供しようとしている標準化グループも存在します。詳細については、次を参照してください。

     http://www.syncml.org

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

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

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

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

これらの 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 オブジェクトに同期メカニズムを選択させることができます。また、jdbc@sun.com でオラクル社に実装の完全指定クラス名を登録することにより、その実装を公開することもできます。この処理の詳細については、次で説明します。

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

  • 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 の派生元のテーブル (複数可) への同期をサポートすることを示す。

      • 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.getDataSourcLock() {
            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 関連項目

  • Java™ Platform
    Standard Edition 7

    バグまたは機能を送信
    詳細な API リファレンスおよび開発者ドキュメントについては、Java SE のドキュメントを参照してください。そのドキュメントには、概念的な概要、用語の定義、回避方法、有効なコード例などの、開発者を対象にしたより詳細な説明が含まれています。
    Copyright © 1993, 2013, Oracle and/or its affiliates. All rights reserved.