Module  java.sql.rowset
软件包  javax.sql.rowset.spi

Interface SyncResolver

  • All Superinterfaces:
    AutoCloseableResultSetRowSetWrapper


    public interface SyncResolver
    extends RowSet
    定义一个框架,允许应用程序使用手动决策树来决定在发生同步冲突时应该做什么。 虽然应用程序不是手动解决同步冲突是强制性的,但是该框架提供了在冲突发生时委托给应用程序的方法。

    请注意,冲突是一种情况,其中RowSet对象的原始值与数据源中的值不匹配,这表示自上次同步以来数据源行已被修改。 还要注意,一个RowSet对象的原始值是它刚刚在最后一次同步之前的值,它们不一定是其初始值。

    SyncResolver对象的描述

    一个SyncResolver对象是一个专门的RowSet对象,实现了SyncResolver接口。 可以作为连接的RowSet对象( JdbcRowSet接口的实现)或连接的RowSet对象( CachedRowSet接口的实现或其子接口之一)来操作。 有关子接口的信息,请参阅javax.sql.rowset程序包说明。 SyncResolver的参考实现实现了CachedRowSet接口,但其他实现可能会选择实现JdbcRowSet接口来满足特定需求。

    在应用程序尝试将RowSet对象与数据源同步(通过调用CachedRowSet方法acceptChanges )并发现一个或多个冲突后,行集的SyncProvider对象将创建一个SyncResolver的实例。 这个新的RowSet对象与正在尝试同步的SyncResolver对象具有相同数量的行和列。 SyncResolver对象包含导致冲突的数据源的值和所有其他值的值为null 此外,它还包含有关每个冲突的信息。

    获取和使用SyncResolver对象

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

    使用解析器 ,应用程序可以使用它来获取有关冲突或冲突的信息。 一个SyncResolver对象(如解析器)跟踪有冲突的每一行的冲突。 它还会对受行组命令影响的表或表放置锁定,以便在当前冲突解决时不再发生冲突。

    以下类型的信息可以从一个SyncResolver对象获得:

    当发生冲突时,正在尝试什么操作

    SyncProvider接口定义了描述可能发生的状态的四个常数。 三个常量描述了一个RowSet对象在发现冲突时尝试执行的操作类型(更新,删除或插入),第四个表示没有冲突。 SyncResolver对象调用方法getStatus时,这些常量是可能的返回值。
      int operation = resolver.getStatus();  

    引起冲突的数据源中的值

    RowSet对象已更改并尝试写入数据源的值也自上次同步以来在数据源中发生更改时,存在冲突。 应用程序可以调用SyncResolver方法getConflictValue以检索数据源中的冲突的原因,因为SyncResolver对象中的值是数据源的冲突值。
      java.lang.Object conflictValue = resolver.getConflictValue(2); 
    请注意, 解析器中的列可以由列号指定,如上一行代码中所述,也可以由列名称指定。

    利用从方法getStatusgetConflictValue检索的信息,应用可以确定在数据源中应该保持哪个值。 然后,应用程序将调用SyncResolver方法setResolvedValue ,该方法将设置要RowSetRowSet对象中的值以及数据源中的值。

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

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

    浏览SyncResolver对象

    因为SyncResolver对象是一个RowSet对象,因此应用程序可以使用所有RowSet方法来移动光标以导航SyncResolver对象。 例如,应用程序可以使用RowSet方法next获取每行,然后调用SyncResolver方法getStatus查看该行是否包含冲突。 在具有一个或多个冲突的行中,应用程序可以遍历列来查找任何非空值,这将是数据源中冲突的值。

    为了更容易地导航SyncResolver对象,特别是当没有冲突的行数很多时, SyncResolver接口定义了方法nextConflictpreviousConflict ,它们仅移动到包含至少一个冲突值的行。 那么应用程序可以调用SyncResolver方法getConflictValue ,提供它的列号,以获得冲突值本身。 下一节的代码片段给出了一个例子。

    代码示例

    下面的代码片段演示了如何断开RowSet对象CRS可能会尝试自己与底层数据源同步,然后解决冲突。 try,CRS调用该方法acceptChanges ,向它传递Connection对象con。 如果没有冲突,则crs中的更改只会写入数据源。 但是,如果有冲突,方法acceptChanges将抛出一个SyncProviderException对象,并且catch块生效。 在这个例子中,其中说明了SyncResolver对象可以使用的多种方式之一, SyncResolver方法nextConflict用于while循环。 nextConflict返回false ,循环将结束,当SyncResolver对象解析器中没有更多的冲突行时,该循环将会发生。 在这个特定的代码片段中, 解析器查找具有更新冲突的行(状态为SyncResolver.UPDATE_ROW_CONFLICT行),并且此代码片段的其余部分仅针对发生冲突的行执行,因为crs正在尝试更新。

    光标进行分解器已移动到下一个冲突行具有更新冲突之后,该方法getRow指示当前行的数目,并且光标为CachedRowSet对象crs被移动到可比较的行中的CRS。 通过在解析器crs中遍历该行的列,可以检索和比较冲突的值以确定应该保留哪个值。 在这个代码片段中, 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对象的原始值不同,这意味着自上次同步以来,数据源中的行已被更新或删除。
        另请参见:
        Constant Field Values
      • DELETE_ROW_CONFLICT

        static final int DELETE_ROW_CONFLICT
        表示在RowSet对象尝试删除数据源中的行时发生冲突。 要更新的数据源行中的值与该行的RowSet对象的原始值不同,这意味着自上次同步以来,数据源中的行已被更新或删除。
        另请参见:
        Constant Field Values
      • INSERT_ROW_CONFLICT

        static final int INSERT_ROW_CONFLICT
        表示在RowSet对象尝试将一行插入数据源时发生冲突。 这意味着自上次同步以来,与要插入的行具有相同主键的行已经被插入到数据源中。
        另请参见:
        Constant Field Values
      • NO_ROW_CONFLICT

        static final int NO_ROW_CONFLICT
        表示RowSet对象尝试更新,删除或插入数据源中的一行时不会发生冲突。 在值SyncResolver将包含null值仅作为指示,在有关冲突解决此行中的信息。
        另请参见:
        Constant Field Values
    • 方法详细信息

      • 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 - 一个 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对象的当前行中的列索引中的值。 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