モジュール 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オブジェクトは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