javax.sql.rowset.spi

接口
异常
第三方供应商在其同步提供者的实现中必须使用的标准类和接口。

请参见:
          描述

接口摘要
SyncResolver 定义一个框架,当发生同步冲突时,它允许应用程序使用手工决策树来确定应该执行的操作。
TransactionalWriter 一个专用接口,用来方便地扩展标准 SyncProvider 抽象类以便拥有细粒度的事务控制。
XmlReader 一个专用接口,用来方便地扩展 SyncProvider 抽象类以用于面向 XML 的同步提供者。
XmlWriter 一个专用接口,用来方便地扩展 SyncProvider 抽象类以用于面向 XML 的同步提供者。
 

类摘要
SyncFactory 该服务提供者接口 (SPI) 机制可以生成由非连接 RowSet 对象使用的 SyncProvider 实例。
SyncProvider 为非连接 RowSet 对象提供 reader/writer 功能的同步机制。
 

异常摘要
SyncFactoryException 指示 SyncFactory 机制发生的错误。
SyncProviderException 指示 SyncProvider 机制发生的错误。
 

软件包 javax.sql.rowset.spi 的描述

第三方供应商在其同步提供者的实现中必须使用的标准类和接口。这些类和接口被称为服务提供者接口 (SPI)。供应商通过向 jdbc@sun.com 发送电子邮件,可以使其实现被 JDBC 网页所包含,该网页列出了可用的 SyncProvider 实现。这样做有助于开发人员了解该实现。为了使 RowSet 对象能够使用实现,供应商必须向 SyncFactory 单件注册。(有关注册过程和所使用命名约定的完整解释,请参阅 SyncProvider 的类注释。)

目录

1.0 包规范

以下类和接口组成了 javax.sql.rowset.spi 包:

  • SyncFactory
  • SyncProvider
  • SyncFactoryException
  • SyncProviderException
  • SyncResolver
  • XmlReader
  • XmlWriter
  • TransactionalWriter
javax.sql 包中的以下接口也是 SPI 的一部分:
  • RowSetReader
  • RowSetWriter

SyncProvider 实现通过以下机制提供非连接 RowSet 对象:将数据读入该对象和将在该对象中修改的数据写回底层数据源。当调用 CachedRowSet 方法 executepopulate 时,readerRowSetReaderXMLReader 对象可以将数据读入 RowSet 对象。当调用 CachedRowSet 方法 acceptChanges 时,writerRowSetWriterXMLWriter 对象可以将更改写回底层数据源。

RowSet 对象中的更改写入其数据源的过程称为同步RowSet 正在使用的 SyncProvider 实现可以确定 RowSet 对象的 writer 所使用的同步级别。同步的各种级别被称为等级

同步的较低等级称为乐观 并发级别,因为它们乐观地假设不存在任何冲突或仅有极少的冲突。当在 RowSet 对象中修改的同一数据也在数据源中修改时,会发生冲突。使用乐观并发模型意味着如果存在冲突,则会丢失对数据源或 RowSet 对象的修改。

同步的较高等级被称为悲观,因为它们假设数据源会被访问并修改。这些等级可以设置各种级别的锁定以增加不发生冲突的几率。

最低级别的同步只将对 RowSet 对象进行的任何更改写入到其底层数据源。writer 不执行任何检查冲突的操作。如果存在冲突,并且数据源值被重写,则其他方对数据源进行的更改会丢失。

RIXMLProvider 实现使用最低级别的同步,并仅将 RowSet 更改写入数据源。确实是这样,因为 XML 数据源通常不会启用事务处理技术来维护数据完整性。但是,特定的标准化组织已经在考虑提供基于 XML 的同步。有关详细信息,请参阅


     http://www.syncml.org

对于下一个级别,writer 会查看是否存在冲突,如果存在,则它不将任何内容写入到数据源。此并发级别的问题是如果另一方在 RowSet 对象获得其数据后修改了数据源中相应数据,则对 RowSet 对象进行的修改会丢失。RIOptimisticProvider 实现使用此级别的同步。

对于称为悲观并发的较高级别的同步,writer 会采取一些步骤(如设置锁定)来避免冲突。设置锁定可以是在一个行上设置,也可以是在一个表或整个数据源上设置。因此,同步级别是一个以下两者间的权衡:用户并发访问数据源的能力和 writer 保持 RowSet 对象及其同步数据源中数据的能力。

它要求所有非连接 RowSet 对象(CachedRowSetFilteredRowSetJoinRowSetWebRowSet 对象)从 SyncFactory 机制获取它们的 SyncProvider 对象。

参考实现 (RI) 提供两个同步提供者。

  • RIOptimisticProvider
    默认的提供者,当未指定任何提供者实现时,SyncFactory 实例将它提供给非连接 RowSet 对象。
    此同步提供者使用乐观并发模型,假设访问数据库中同一数据的用户之间几乎没有冲突。它避免了使用锁定;相反,它会查看在尝试使 RowSet 对象和数据源同步之前是否存在冲突。如果存在冲突,它不执行任何操作,这意味着对 RowSet 对象的更改不会保留到数据源。
  • RIXMLProvider
    可以与 WebRowSet 对象一起使用的同步提供者,它是一个以 XML 格式写入或以 XML 格式进行读取的 rowset。RIXMLProvider 实现根本不检查任何冲突,仅将 WebRowSet 对象中的任何更新数据写入底层数据源。WebRowSet 对象处理 XML 数据时使用此提供者。
这些 SyncProvider 实现与参考实现捆绑在一起,使它们总是可用于 RowSet 实现。 SyncProvider 实现通过向单一 SyncFactory 注册使它们本身可用。当 RowSet 对象通过在构造方法中指定某个提供者,或者指定它作为 CachedRowSet 方法 setSyncProvider 的参数来请求该提供者时,该单一 SyncFactory 会查看请求的提供者是否已向它注册。如果已注册,则 SyncFactory 创建一个它的实例,并将它传递到发出请求的 RowSet 对象。如果指定的 SyncProvider 实现没有注册,则单一 SyncFactory 导致抛出 SyncFactoryException 对象。如果不指定任何提供者,则单一 SyncFactory 将创建一个默认的提供者实现 RIOptimisticProvider 的实例,并将它传递到发出请求的 RowSet 对象。

如果 WebRowSet 对象在其构造方法中未指定提供者,则 SyncFactory 将为它提供一个 RIOptimisticProvider 实例。但是,可以实现 WebRowSet 的构造方法来将提供者设置为 RIXMLProvider,它以 XML 格式读取和写入 RowSet 对象。

有关更多详细信息,请参阅 SyncProvider 类规范。

供应商可以使用任何一个可能级别的同步开发 SyncProvider 实现,从而给 RowSet 对象一个选择同步机制的机会。供应商通过向 jdbc@sun.com 的 Sun Microsystems 注册完全限定类名称使其实现可用。下面将更加详细地讨论此过程。

2.0 服务提供者接口架构

  • 3.0 SyncProvider 实现者指南

      3.1 要求

      完全可插入到 SyncFactory 的兼容 SyncProvider 实现必须扩展和实现 SyncProvider 类中所有的抽象方法。另外,实现必须确定 SyncProvider 类定义中定义的等级、锁定和可更新视图的功能。必须支持一个或多个 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_MODIFIEDGRADE_LOCK_WHEN_LOADED 允许非连接 RowSet 对象对锁定程度进行细粒度控制。

      • DATASOURCE_NO_LOCK - 在原始的数据源上不保留任何锁定。如果 RowSet 对象没有其他指示,则这是所有 SyncProvider 实现的默认锁定设置。

      • DATASOURCE_ROW_LOCK - 对行进行锁定,用于填充 RowSet 对象的原始 SQL 查询会涉及这些行。

      • DATASOURCE_TABLE_LOCK - 对所有表进行锁定,用于填充 RowSet 对象的查询会涉及这些表。

      • DATASOURCE_DB_LOCKRowSet 对象使用的整个数据源进行锁定。

      3.4 可更新的视图

      使用 SQL VIEW 中的数据可以填充 RowSet 对象。以下常量指示 SyncProvider 对象是否可以更新从中衍生出 VIEW 的表中的数据。

      • UPDATABLE_VIEW_SYNC 指示 SyncProvider 实现支持对从中衍生出用于填充 RowSet 对象的 SQL VIEW 的表的同步。

      • NONUPDATABLE_VIEW_SYNC 指示 SyncProvider 实现支持对从中衍生出用于填充 RowSet 对象的 SQL VIEW 的表的同步。

      3.5 SyncProvider 等级和锁定的用法

      在下面的示例中,引用 CachedRowSetImpl 实现通过调用 setSyncProvider 方法重新配置其当前 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 类中的静态实用工具方法也能够确定当前向 SyncFactory 注册的 SyncProvider 实现所组成的列表。
              Enumeration e = SyncFactory.getRegisteredProviders();
      

    4.0 解决同步冲突

    接口 SyncResolver 提供了一种应用程序手动确定发生冲突时应执行的操作的方式。当 CachedRowSet 方法 acceptChanges 完成并检测到一个或多个冲突时,它将抛出一个 SyncProviderException 对象。应用程序可以捕获该异常,并通过调用方法 SyncProviderException.getSyncResolver() 使它检索 SyncResolver 对象。

    SyncResolver 对象是实现了 SyncResolver 接口的一种特殊 CachedRowSet 对象或 JdbcRowSet 对象,它逐行检查冲突。它与同步的 RowSet 对象完全相同,区别在于它仅包含数据源中导致冲突的数据。将所有其他列值都设置为 null。为了从一个冲突值导航到另一个冲突值,SyncResolver 对象提供了方法 nextConflictpreviousConflict

    SyncResolver 接口也提供了一些方法,用于执行以下操作:

    • 查明冲突是否涉及到更新、删除或插入
    • 获取数据源中导致冲突的值
    • 设置应在数据源中的值(如果它需要更改)或设置应在 RowSet 对象中的值(如果它需要更改)

    在调用 CachedRowSet 方法 acceptChanges 时,它会委托给 RowSet 对象的 SyncProvider 对象。实现的 SyncProvider 对象提供 writer 的方式决定对冲突执行检查的级别(等级)。完成所有的冲突检查并且找到一个或多个冲突之后,方法 acceptChanges 会抛出一个 SyncProviderException 对象。应用程序可以捕获该异常,并使用该异常获取 SyncResolver 对象。

    然后,应用程序可以使用 SyncResolver 方法获取关于每个冲突的信息,并决定要执行的操作。如果应用程序逻辑或用户决定 RowSet 对象中的值应该保留,那么应用程序或用户可以使用它重写数据源值。

    SyncResolver 接口的注释有更多详细信息。

    5.0 相关的规范

    6.0 相关的文档