JavaTM Platform
Standard Ed. 6

javax.sql.rowset.spi
接口 SyncResolver

所有超级接口:
ResultSet, RowSet, Wrapper

public interface SyncResolver
extends RowSet

定义一个框架,当发生同步冲突时,它允许应用程序使用手工决策树来确定应该执行的操作。虽然应用程序手工解决同步冲突并不是委托过程,但此框架还是提供了一些发生冲突时委托应用程序的方法。

注意,冲突是指 RowSet 对象的原始行值与数据源中的值不匹配的情况,它指示自最后一次同步以来数据源行已被修改。还要注意,RowSet 对象的原始值就是最后一次同步之前的值,不必是其初始值。

SyncResolver 对象的描述

SyncResolver 对象是实现 SyncResolver 接口的专用 RowSet 对象。它可以以连接的 RowSet 对象(JdbcRowSet 接口的实现)或非连接 RowSet 对象(CachedRowSet 接口或其一个子接口的实现)的形式进行操作。有关子接口的信息,请参阅 javax.sql.rowset 包描述。SyncResolver 的参考实现实现了 CachedRowSet 接口,但是其他实现可以选择实现 JdbcRowSet 接口,以满足特定的需要。

应用程序尝试使 RowSet 对象与数据源同步(通过调用 CachedRowSet 方法 acceptChanges),并且找到一个或多个冲突之后,rowset 的 SyncProvider 对象会创建一个 SyncResolver 实例。这一新的 SyncResolver 对象具有与正在尝试同步的 RowSet 对象相同的行数和列数。SyncResolver 对象包含数据源中导致冲突的值,其他值都为 null。另外,它包含关于每个冲突的信息。

获取并使用 SyncResolver 对象

当方法 acceptChanges 遇到冲突时,SyncProvider 对象会创建 SyncProviderException 对象,并使用新的 SyncResolver 对象设置它。方法 acceptChanges 将抛出此异常,然后应用程序可以捕获它并用以获取它包含的 SyncResolver 对象。以下代码片段使用 SyncProviderException 方法 getSyncResolver 来获取 SyncResolver 对象 resolver
     } catch (SyncProviderException spe) {
         SyncResolver resolver = spe.getSyncResolver();
     ...
     }
 

通过所拥有的 resolver,应用程序可以使用它获取关于冲突的信息。SyncResolver 对象(如 resolver)跟踪存在冲突的每个行中的冲突。它还可以锁定受 rowset 命令影响的表,以便在解决当前冲突时不再发生其他冲突。

可以从 SyncResolver 对象获取以下几种信息:

  • 发生冲突时正试图进行的操作
    SyncProvider 接口定义了四个常量来描述可能发生的状态。其中三个常量描述发现冲突时 RowSet 对象正试图执行的操作类型(更新、删除或插入),第四个常量指示不存在冲突。当 SyncResolver 对象调用方法 getStatus 时,这些常量都是可能的返回值。
         int operation = resolver.getStatus();
     

  • 数据源中导致冲突的值
    RowSet 对象更改并尝试写入到数据源的值自上一次同步以来也在数据源中被更改时,会发生冲突。应用程序可以调用 SyncResolver 的方法 getConflictValue来获取数据源中导致冲突的值,因为 SyncResolver 对象中的值是取自数据源的冲突值。
         java.lang.Object conflictValue = resolver.getConflictValue(2);
     
    注意,resolver 中的列可以使用列号指定(如以上代码行中所示),也可以用列名称指定。

    使用从方法 getStatusgetConflictValue 获取到的信息,应用程序可以做出应在数据源中保留哪一个值的决定。然后,应用程序调用 SyncResolver 的方法 setResolvedValue,它可以设置 RowSet 对象中和数据源中要保留的值。

         resolver.setResolvedValue("DEPT", 8390426);
     
    在以上代码行中,列名称指定 RowSet 对象中要使用给定值设置的列。也可以用列号来指定列。

    解决当前冲突行中的所有冲突之后,应用程序会调用方法 setResolvedValue,并对 SyncResolver 对象中每个冲突行重复此过程。

    导航 SyncResolver 对象

    因为 SyncResolver 对象是 RowSet 对象,所以应用程序可以使用所有的 RowSet 方法移动指针来导航 SyncResolver 对象。例如,应用程序可以使用 RowSet 的方法 next 到达每个行,然后调用 SyncResolver 的方法 getStatus 查看行是否包含冲突。在具有一个或多个冲突的行中,应用程序可以迭代列来查找任何非 null 值,它将是数据源中处于冲突状态的值。

    要使导航 SyncResolver 对象更容易,尤其是存在大量没有冲突的行时,SyncResolver 接口定义了方法 nextConflictpreviousConflict,它们只移动到至少包含一个冲突值的行。然后,应用程序通过提供列号作为参数调用 SyncResolver 的方法 getConflictValue,以获取冲突值本身。下一节中的代码片段给出了一个示例。

    代码示例

    以下代码片段演示非连接 RowSet 对象 crs 如何尝试使自已与底层数据源同步,然后解决冲突。在 try 块中,crs 调用方法 acceptChanges,将 Connection 对象 con 传递给它。如果不存在冲突,则将 crs 中的更改写入到数据源即可。但是,如果存在冲突,则方法 acceptChanges 将抛出 SyncProviderException 对象,catch 块生效。在此示例中,阐述了多种 SyncResolver 对象使用方式中的一种,在 while 循环中,使用 SyncResolver 的方法 nextConflictnextConflict 返回 false 时循环将终止,这发生在 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);
                          } 
                      } 
                  }
              }
          }
     


    字段摘要
    static int DELETE_ROW_CONFLICT
              指示在 RowSet 对象试图删除数据源中的行时发生冲突。
    static int INSERT_ROW_CONFLICT
              指示在 RowSet 对象试图将行插入数据源中时发生冲突。
    static int NO_ROW_CONFLICT
              指示在 RowSet 对象试图更新、删除或插入数据源中的行时发生任何冲突。
    static int UPDATE_ROW_CONFLICT
              指示在 RowSet 对象试图更新数据源中的行时发生冲突。
     
    从接口 java.sql.ResultSet 继承的字段
    CLOSE_CURSORS_AT_COMMIT, CONCUR_READ_ONLY, CONCUR_UPDATABLE, FETCH_FORWARD, FETCH_REVERSE, FETCH_UNKNOWN, HOLD_CURSORS_OVER_COMMIT, TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, TYPE_SCROLL_SENSITIVE
     
    方法摘要
     Object getConflictValue(int index)
              获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。
     Object getConflictValue(String columnName)
              获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。
     int getStatus()
              获取此 SyncResolver 的当前行的冲突状态,它指示在发生冲突时 RowSet 对象正尝试的操作。
     boolean nextConflict()
              将指针从其当前位置移动到下一个包含冲突值的行。
     boolean previousConflict()
              将指针从其当前位置移动到此 SyncResolver 对象中上一个冲突行。
     void setResolvedValue(int index, Object obj)
              将 obj 设置为将同步的 RowSet 对象当前行中第 index 列的值。
     void setResolvedValue(String columnName, Object obj)
              将 obj 设置为将同步的 RowSet 对象当前行中列 columnName 的值。
     
    从接口 javax.sql.RowSet 继承的方法
    addRowSetListener, clearParameters, execute, getCommand, getDataSourceName, getEscapeProcessing, getMaxFieldSize, getMaxRows, getPassword, getQueryTimeout, getTransactionIsolation, getTypeMap, getUrl, getUsername, isReadOnly, removeRowSetListener, setArray, setAsciiStream, setAsciiStream, setAsciiStream, setAsciiStream, setBigDecimal, setBigDecimal, setBinaryStream, setBinaryStream, setBinaryStream, setBinaryStream, setBlob, setBlob, setBlob, setBlob, setBlob, setBlob, setBoolean, setBoolean, setByte, setByte, setBytes, setBytes, setCharacterStream, setCharacterStream, setCharacterStream, setCharacterStream, setClob, setClob, setClob, setClob, setClob, setClob, setCommand, setConcurrency, setDataSourceName, setDate, setDate, setDate, setDate, setDouble, setDouble, setEscapeProcessing, setFloat, setFloat, setInt, setInt, setLong, setLong, setMaxFieldSize, setMaxRows, setNCharacterStream, setNCharacterStream, setNCharacterStream, setNCharacterStream, setNClob, setNClob, setNClob, setNClob, setNClob, setNClob, setNString, setNString, setNull, setNull, setNull, setNull, setObject, setObject, setObject, setObject, setObject, setObject, setPassword, setQueryTimeout, setReadOnly, setRef, setRowId, setRowId, setShort, setShort, setSQLXML, setSQLXML, setString, setString, setTime, setTime, setTime, setTime, setTimestamp, setTimestamp, setTimestamp, setTimestamp, setTransactionIsolation, setType, setTypeMap, setURL, setUrl, setUsername
     
    从接口 java.sql.ResultSet 继承的方法
    absolute, afterLast, beforeFirst, cancelRowUpdates, clearWarnings, close, deleteRow, findColumn, first, getArray, getArray, getAsciiStream, getAsciiStream, getBigDecimal, getBigDecimal, getBigDecimal, getBigDecimal, getBinaryStream, getBinaryStream, getBlob, getBlob, getBoolean, getBoolean, getByte, getByte, getBytes, getBytes, getCharacterStream, getCharacterStream, getClob, getClob, getConcurrency, getCursorName, getDate, getDate, getDate, getDate, getDouble, getDouble, getFetchDirection, getFetchSize, getFloat, getFloat, getHoldability, getInt, getInt, getLong, getLong, getMetaData, getNCharacterStream, getNCharacterStream, getNClob, getNClob, getNString, getNString, getObject, getObject, getObject, getObject, getRef, getRef, getRow, getRowId, getRowId, getShort, getShort, getSQLXML, getSQLXML, getStatement, getString, getString, getTime, getTime, getTime, getTime, getTimestamp, getTimestamp, getTimestamp, getTimestamp, getType, getUnicodeStream, getUnicodeStream, getURL, getURL, getWarnings, insertRow, isAfterLast, isBeforeFirst, isClosed, isFirst, isLast, last, moveToCurrentRow, moveToInsertRow, next, previous, refreshRow, relative, rowDeleted, rowInserted, rowUpdated, setFetchDirection, setFetchSize, updateArray, updateArray, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateAsciiStream, updateBigDecimal, updateBigDecimal, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBinaryStream, updateBlob, updateBlob, updateBlob, updateBlob, updateBlob, updateBlob, updateBoolean, updateBoolean, updateByte, updateByte, updateBytes, updateBytes, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateCharacterStream, updateClob, updateClob, updateClob, updateClob, updateClob, updateClob, updateDate, updateDate, updateDouble, updateDouble, updateFloat, updateFloat, updateInt, updateInt, updateLong, updateLong, updateNCharacterStream, updateNCharacterStream, updateNCharacterStream, updateNCharacterStream, updateNClob, updateNClob, updateNClob, updateNClob, updateNClob, updateNClob, updateNString, updateNString, updateNull, updateNull, updateObject, updateObject, updateObject, updateObject, updateRef, updateRef, updateRow, updateRowId, updateRowId, updateShort, updateShort, updateSQLXML, updateSQLXML, updateString, updateString, updateTime, updateTime, updateTimestamp, updateTimestamp, wasNull
     
    从接口 java.sql.Wrapper 继承的方法
    isWrapperFor, unwrap
     

    字段详细信息

    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_CONFLICTSyncResolver.NO_ROW_CONFLICT

    getConflictValue

    Object getConflictValue(int index)
                            throws SQLException
    获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。

    参数:
    index - 一个 int,它指定此 SyncResolver 对象的此行中的列,从该列可以获取导致冲突的值
    返回:
    SyncResolver 对象的当前行中指定列的值
    抛出:
    SQLException - 如果发生数据库访问错误

    getConflictValue

    Object getConflictValue(String columnName)
                            throws SQLException
    获取此 SyncResolver 对象的当前行中指定列的值,它是数据源中导致冲突的值。

    参数:
    columnName - String 对象,它指定此 SyncResolver 对象的此行中的列,从该列可以获取导致冲突的值
    返回:
    SyncResolver 对象的当前行中指定列的值
    抛出:
    SQLException - 如果发生数据库访问错误

    setResolvedValue

    void setResolvedValue(int index,
                          Object obj)
                          throws SQLException
    obj 设置为将同步的 RowSet 对象当前行中第 index 列的值。将 obj 内部地设置为数据源中的值。

    参数:
    index - 一个 int,它提供要设置保留值的列号
    obj - 一个 Object,它是在 RowSet 对象中设置的值,将它保留在数据源中
    抛出:
    SQLException - 如果发生数据库访问错误

    setResolvedValue

    void setResolvedValue(String columnName,
                          Object obj)
                          throws SQLException
    obj 设置为将同步的 RowSet 对象当前行中列 columnName 的值。将 obj 内部地设置为数据源中的值。

    参数:
    columnName - String 对象,它提供要设置保留值的列名称
    obj - 一个 Object,它是在 RowSet 对象中设置的值,将它保留在数据源中
    抛出:
    SQLException - 如果发生数据库访问错误

    nextConflict

    boolean nextConflict()
                         throws SQLException
    将指针从其当前位置移动到下一个包含冲突值的行。SyncResolver 对象的指针最初位于第一个冲突行之前;第一次调用 nextConflict 方法使第一个冲突行成为当前行;第二次调用使第二个冲突行成为当前行,依此类推。

    调用方法 nextConflict 将隐式关闭输入流(如果有打开的输入流),并且将清除 SyncResolver 对象的警告链。

    返回:
    如果新的当前行有效,则返回 true;如果不存在下一行,则返回 false
    抛出:
    SQLException - 如果发生数据库访问错误,或者结果集类型为 TYPE_FORWARD_ONLY

    previousConflict

    boolean previousConflict()
                             throws SQLException
    将指针从其当前位置移动到此 SyncResolver 对象中上一个冲突行。

    调用方法 previousConflict 将隐式关闭输入流(如果有打开的输入流),并且将清除 SyncResolver 对象的警告链。

    返回:
    如果指针位于有效行上,则返回 true;如果它不在结果集中,则返回 false
    抛出:
    SQLException - 如果发生数据库访问错误,或者结果集类型为 TYPE_FORWARD_ONLY

    JavaTM Platform
    Standard Ed. 6

    提交错误或意见
    有关更多的 API 参考资料和开发人员文档,请参阅 Java SE 开发人员文档。该文档包含更详细的、面向开发人员的描述,以及总体概述、术语定义、使用技巧和工作代码示例。

    版权所有 2007 Sun Microsystems, Inc. 保留所有权利。 请遵守许可证条款。另请参阅文档重新分发政策