モジュール java.sql.rowset
パッケージ javax.sql.rowset.spi

インタフェースSyncResolver

すべてのスーパー・インタフェース:
AutoCloseable, ResultSet, RowSet, Wrapper

public interface SyncResolver extends RowSet
アプリケーションが、手動の意志決定ツリーを使って同期競合が発生したときの対処方法を決定できるようにするフレームワークを定義します。 アプリケーションが同期競合を手動で解決することは必須ではありませんが、このフレームワークは競合が発生したときにアプリケーションに委譲する手段を提供します。

競合とは、RowSetオブジェクトの元の行の値がデータ・ソース内の値と一致しない状態であり、前回の同期以降にデータ・ソース行が変更されたことを示します。 RowSetオブジェクトの元の値は、前回の同期の直前の値であり、必ずしも初期値ではありません。

SyncResolverオブジェクトの説明

SyncResolverオブジェクトは、SyncResolverインタフェースを実装する特殊なRowSetオブジェクトです。 これは接続されたRowSetオブジェクト(JdbcRowSetインタフェースの実装)または未接続のRowSetオブジェクト(CachedRowSetインタフェースまたはそのサブインタフェースの実装)として動作できます サブインタフェースについては、javax.sql.rowsetパッケージの説明を参照してください。 SyncResolverのリファレンス実装はCachedRowSetインタフェースを実装しますが、ほかの実装では、JdbcRowSetインタフェースを実装して、特定の必要を満たすことができます。

アプリケーションが(CachedRowSetacceptChangesメソッドを呼び出して) RowSetオブジェクトとデータ・ソースを同期させようとした後、いくつかの競合が発見されると、行セットのSyncProviderオブジェクトはSyncResolverのインスタンスを作成します。 この新しいSyncResolverオブジェクトは同期を試みたRowSetオブジェクトと同じ行数および列数になります。 SyncResolverオブジェクトには、競合が発生したデータ・ソースの値が格納され、ほかのすべての値にはnullが格納されます。 さらに、各競合の情報も格納されます。

SyncResolverオブジェクトの取得と使用

acceptChangesメソッドが競合を検出すると、SyncProviderオブジェクトはSyncProviderExceptionオブジェクトを作成し、それに新しいSyncResolverオブジェクトを設定します。 acceptChangesメソッドはこの例外をスローし、それをアプリケーションがキャッチし、格納されているSyncResolverオブジェクトの取得に使用します。 次のコード部分では、SyncProviderExceptiongetSyncResolverメソッドを使用して、SyncResolverオブジェクトresolverを取得します。
 
      catch (SyncProviderException spe) {
         SyncResolver resolver = spe.getSyncResolver();
     ...
     }

 }
 

アプリケーションは、resolverを使って、そこに含まれる競合(複数可)の情報を取得できます。 resolverなどのSyncResolverオブジェクトは、競合がある各行で、その競合を追跡します。 また、行セットのコマンドの影響を受けるテーブル(複数可)にロックを適用して、現在の競合が解決されるまで新たに競合が発生しないようにします。

SyncResolverオブジェクトから取得可能な情報は、次のとおりです。

競合発生時に試みられていた操作

SyncProviderインタフェースは、発生する可能性のある状態について説明する4つの定数を定義します。 3つの定数は、競合が検出されたときRowSetオブジェクトが試行していた操作の種類(更新、削除、または挿入)を表し、4番目は競合がないことを表します。 SyncResolverオブジェクトがgetStatusメソッドを呼び出したとき、これらの定数が戻り値として返される可能性のあるものです。
     int operation = resolver.getStatus(); 
 

競合の原因になったデータ・ソース内の値

RowSetオブジェクトによって値が変更され、データ・ソースに書き込まれるとき、書込み先のデータ・ソース内の値が前回同期処理を行なった時点とは異なっていた場合、競合が発生したことを表します。 SyncResolverオブジェクトの値がデータ・ソースの競合値であるため、アプリケーションはSyncResolvergetConflictValueメソッドを呼び出して、競合の原因となったデータ・ソース内の値を取り出すことができます。
     java.lang.Object conflictValue = resolver.getConflictValue(2);
 
resolverの列は、上のコード例のように列番号で指定できます。列名で指定することもできます。

アプリケーションは、getStatusメソッドおよびgetConflictValueメソッドから取得された情報を使って、データ・ソース内に保持すべき値を決定できます。 続いて、SyncResolversetResolvedValueメソッドを呼び出して、RowSetオブジェクトおよびデータ・ソースに保持する値を設定します。

     resolver.setResolvedValue("DEPT", 8390426);
 
上のコード例では、列名によって、指定の値を設定されるRowSetオブジェクト内の列を指定しています。 列番号で列を指定することもできます。

アプリケーションは現在の競合する行のすべての競合を解決したら、setResolvedValueメソッドを呼び出し、SyncResolverオブジェクトの競合する行ごとにこの手順を繰り返します。

SyncResolverオブジェクトのナビゲート

SyncResolverオブジェクトはRowSetオブジェクトであるため、アプリケーションはすべてのRowSetメソッドを使用して、カーソルを動かし、SyncResolverオブジェクトをナビゲートできます。 たとえば、アプリケーションはRowSetnextメソッドを使用して、各行に移動し、SyncResolvergetStatusメソッドを呼び出して、行に競合が含まれるかどうかを確認できます。 競合を含む行では、アプリケーションは列で反復処理を行い、null以外の値を見つけることができます。この値は競合のあるデータ・ソースの値になります。

SyncResolverオブジェクトのナビゲートを簡単にするには、特に大半の行に競合がない場合に、SyncResolverインタフェースでnextConflictメソッドおよびpreviousConflictメソッドを定義します。これらのメソッドは、少なくとも1つの競合値を含む行のみを移動します。 続いてアプリケーションで列番号を指定して、SyncResolvergetConflictValueメソッドを呼び出し、競合値自体を取得します。 次のセクションのコードの抜粋に例を示します。

コード例

次のコードの抜粋は、未接続のRowSetオブジェクトcrsが自身を配下のデータ・ソースと同期することで、競合を解決する方法を示しています。 tryブロックで、crsacceptChangesメソッドを呼び出し、Connectionオブジェクトconを渡しています。 競合がない場合は、単にcrsの変更がデータ・ソースに書き込まれます。 しかし、競合がある場合は、acceptChangesメソッドがSyncProviderExceptionオブジェクトをスローし、catchブロックが有効になります。 この例では、SyncResolverオブジェクトを使用した多くの方法のうちの1つを説明しており、SyncResolvernextConflictメソッドをwhileループで使用しています。 nextConflictfalseを返す(SyncResolverオブジェクトresolverに競合する行がなくなる)とループが終了します。 この特定のコードの抜粋では、resolverは競合を更新した行(SyncResolver.UPDATE_ROW_CONFLICTのステータスの行)を検索し、このコードの抜粋の残りの部分は、crsが更新を試みたために競合が発生した行に対してのみ実行されます。

resolverのカーソルが更新競合のある次の競合する行に移動した後、getRowメソッドは現在の行を示し、CachedRowSetオブジェクトcrsのカーソルはcrsの比較可能な行に移動します。 resolvercrsの両方の行の列で繰返し処理を行うことによって、競合している値を取得し、比較して、保持する値を決定します。 このコードの抜粋では、crsの値が解決済みの値として設定された値であり、これを使用して、データ・ソースの競合する値が上書きされることを意味します。

 
     try {

         crs.acceptChanges(con);

     } catch (SyncProviderException spe) {

         SyncResolver resolver = spe.getSyncResolver();

         Object crsValue;  // value in the RowSet object
         Object resolverValue:  // value in the SyncResolver object
         Object resolvedValue:  // value to be persisted

         while(resolver.nextConflict())  {
             if(resolver.getStatus() == SyncResolver.UPDATE_ROW_CONFLICT)  {
                 int row = resolver.getRow();
                 crs.absolute(row);

                 int colCount = crs.getMetaData().getColumnCount();
                 for(int j = 1; j <= colCount; j++) {
                     if (resolver.getConflictValue(j) != null)  {
                         crsValue = crs.getObject(j);
                         resolverValue = resolver.getConflictValue(j);
                         . . .
                         // compare crsValue and resolverValue to determine
                         // which should be the resolved value (the value to persist)
                         resolvedValue = crsValue;

                         resolver.setResolvedValue(j, resolvedValue);
                      }
                  }
              }
          }
      }
 

導入されたバージョン:
1.5
  • フィールド詳細

    • UPDATE_ROW_CONFLICT

      static final int UPDATE_ROW_CONFLICT
      RowSetオブジェクトがデータ・ソース内の行の更新を試行したとき、競合が発生したことを表します。 データ・ソース内の更新対象の行の値は、RowSetオブジェクトの該当する行の元の値とは異なっています。つまり、データ・ソース内の行は、前回の同期処理の後更新されたか、削除されています。
      関連項目:
      定数フィールド値
    • DELETE_ROW_CONFLICT

      static final int DELETE_ROW_CONFLICT
      RowSetオブジェクトがデータ・ソース内の行の削除を試行したとき、競合が発生したことを表します。 データ・ソース内の更新対象の行の値は、RowSetオブジェクトの該当する行の元の値とは異なっています。つまり、データ・ソース内の行は、前回の同期処理の後更新されたか、削除されています。
      関連項目:
      定数フィールド値
    • INSERT_ROW_CONFLICT

      static final int INSERT_ROW_CONFLICT
      RowSetオブジェクトがデータ・ソースへの行の挿入を試行したとき、競合が発生したことを表します。 前回の更新のあと、データ・ソースに挿入しようとした行と同じ主キーを持つ行が、すでに挿入されています。
      関連項目:
      定数フィールド値
    • NO_ROW_CONFLICT

      static final int NO_ROW_CONFLICT
      RowSetオブジェクトがデータ・ソース内の行の更新、削除、または挿入を試行したとき、競合は発生しなかったことを表します。 SyncResolver内の値にはnull値が含まれますが、これはこの行内に、競合の解決に関連する情報が含まれていないことを表しています。
      関連項目:
      定数フィールド値
  • メソッドの詳細

    • getStatus

      int getStatus()
      このSyncResolverの現在の行の競合ステータスを取得します。これは、競合が発生したときRowSetオブジェクトが試行していた操作を表します。
      戻り値:
      次の定数のいずれか。SyncResolver.UPDATE_ROW_CONFLICTSyncResolver.DELETE_ROW_CONFLICTSyncResolver.INSERT_ROW_CONFLICT、またはSyncResolver.NO_ROW_CONFLICT
    • getConflictValue

      Object getConflictValue(int index) throws SQLException
      このSyncResolverオブジェクトの現在の行にある指定された列の値を取得します。この値が、競合の原因となったデータ・ソース内の値です。
      パラメータ:
      index - このSyncResolverオブジェクトのこの行内の列を指定するint。この列から、競合の原因となった値を取得する
      戻り値:
      このSyncResolverオブジェクトの現在の行の指定された列の値
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合
    • getConflictValue

      Object getConflictValue(String columnName) throws SQLException
      このSyncResolverオブジェクトの現在の行にある指定された列の値を取得します。この値が、競合の原因となったデータ・ソース内の値です。
      パラメータ:
      columnName - このSyncResolverオブジェクトのこの行内の列を指定するStringオブジェクト。この列から、競合の原因となった値を取得する
      戻り値:
      このSyncResolverオブジェクトの現在の行の指定された列の値
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合
    • setResolvedValue

      void setResolvedValue(int index, Object obj) throws SQLException
      objを、同期するRowSetオブジェクトの現在の行の列index内の値として設定します。objは、内部でデータ・ソース内に値として設定されます。
      パラメータ:
      index - 列番号を指定するint。この列に、保持する値を設定する
      obj - RowSetオブジェクトに設定され、データ・ソースに残される値を示すObject
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合
    • setResolvedValue

      void setResolvedValue(String columnName, Object obj) throws SQLException
      objを、同期するRowSetオブジェクトの現在の行の列columnName内の値として設定します。objは、内部でデータ・ソース内に値として設定されます。
      パラメータ:
      columnName - 列名を指定するStringオブジェクト。この列に、保持する値を設定する
      obj - RowSetオブジェクトに設定され、データ・ソースに残される値を示すObject
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合
    • nextConflict

      boolean nextConflict() throws SQLException
      カーソルを現在の位置から、競合する値を含む次の行に移動します。 SyncResolverオブジェクトのカーソルは、初期状態では最初の競合する行の前に位置付けられます。nextConflictメソッドの最初の呼出しによって、最初の競合する行が現在の行になります。2回目の呼出しによって2番目の競合する行が現在の行になり、以下同様に続きます。

      nextConflictメソッドへの呼出しによって、入力ストリームが開いていれば、暗黙的に閉じられ、SyncResolverオブジェクトの警告チェーンがクリアされます。

      戻り値:
      新しい現在の行が有効である場合はtrue、行がそれ以上存在しない場合はfalse
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合、または結果セットの型がTYPE_FORWARD_ONLYの場合
    • previousConflict

      boolean previousConflict() throws SQLException
      カーソルを現在の位置から、このSyncResolverオブジェクト内の前の競合する行に移動します。

      previousConflictメソッドへの呼出しによって、入力ストリームが開いていれば、暗黙的に閉じられ、SyncResolverオブジェクトの警告チェーンがクリアされます。

      戻り値:
      カーソルが有効な行にある場合はtrue、結果セットの外にある場合はfalse
      例外:
      SQLException - データベース・アクセス・エラーが発生した場合、または結果セットの型がTYPE_FORWARD_ONLYの場合