ナビゲーション・リンクをスキップ
Java(tm) Platform
Standard Edition 8

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

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

参照: 説明

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

サード・パーティ・ベンダーが同期プロバイダの実装で使用する必要がある標準クラスおよびインタフェースです。これらのクラスおよびインタフェースをまとめて、「サービス・プロバイダ・インタフェース(Service Provider Interface、SPI)」と呼びます。使用可能なSyncProvider実装の一覧が記載されたJDBC Webページにベンダー固有の実装を追加して、開発者に実装を公開したい場合は、[email protected]まで電子メールにてご連絡ください。そうすれば、開発者がその実装に気づきやすくなります。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オブジェクトに同期メカニズムを選択させることができます。また、[email protected]でOracle社に実装の完全指定クラス名を登録することにより、その実装を公開することもできます。この処理の詳細については、次で説明します。

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(tm) Platform
    Standard Edition 8

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