Package javax.sql.rowset.spi
RowSet
对象能够使用实现,供应商必须使用SyncFactory
单例注册它。
(有关注册过程和使用的命名约定的完整说明,请参阅SyncProvider
的类注释。)
目录
- 1.0 Package Specification
- 2.0 Service Provider Architecture
- 3.0 Implementer's Guide
- 4.0 Resolving Synchronization Conflicts
- 5.0 Related Specifications
- 6.0 Related Documentation
1.0 Package Specification
以下类和接口组成了javax.sql.rowset.spi
软件包:
-
SyncFactory
-
SyncProvider
-
SyncFactoryException
-
SyncProviderException
-
SyncResolver
-
XmlReader
-
XmlWriter
-
TransactionalWriter
javax.sql
包中也是SPI的一部分:
-
RowSetReader
-
RowSetWriter
一个SyncProvider
实现提供了一个断开连接的RowSet
对象,具有读取数据的机制,并将已经修改的数据写入底层数据源。 读者 , RowSetReader
或XMLReader
对象,当CachedRowSet
方法execute
或populate
时,将数据读入RowSet
对象。 作者 ,一个RowSetWriter
或XMLWriter
对象,当调用CachedRowSet
方法acceptChanges
时, CachedRowSet
acceptChanges
回底层数据源。
将RowSet
对象中的更改写入其数据源的过程称为同步 。 RowSet
对象正在使用的SyncProvider
实现决定了RowSet
对象的作者使用的同步级别。 各种级别的同步被称为等级 。
较低等级的同步被称为乐观并发级别,因为它们乐观地假设不会有冲突或很少的冲突。 当在数据源中修改了RowSet
对象中修改的相同数据时,存在冲突。 使用乐观并发模型意味着如果存在冲突,则会丢失对数据源或RowSet
对象的修改。
更高等级的同步被称为悲观,因为他们假设其他人将访问数据源并进行修改。 这些等级设置不同级别的锁以增加没有发生冲突的机会。
最低级别的同步只是将对RowSet
对象的任何更改写入其底层数据源。 作家什么也不做任何检查冲突。 如果存在冲突并且数据源值被覆盖,则其他方对数据源所做的更改将丢失。
RIXMLProvider
实现使用最低级别的同步,只是将RowSet
更改写入数据源。
对于下一个级别,作者检查是否存在任何冲突,如果有的话,它不会对数据源写任何内容。 这种并发级别的问题是,如果另一方已经修改了数据源中的相应数据,因为RowSet
对象获得了其数据,则对RowSet
对象所做的更改将丢失。 RIOptimisticProvider
实现使用这种级别的同步。
在较高级别的同步,称为悲观并发,作者采取措施通过设置锁来避免冲突。 设置锁可以从设置单个行的锁定到在表或整个数据源上设置锁定而有所不同。 因此,同步级别是用户同时访问数据源的能力与作者将数据保持在RowSet
对象及其数据源同步的能力之间的折衷。
这是所有断开的要求RowSet
对象( CachedRowSet
, FilteredRowSet
, JoinRowSet
,并WebRowSet
对象)获得其SyncProvider
从对象SyncFactory
机制。
参考实现(RI)提供了两个同步提供程序。
-
RIOptimisticProvider
当未指定提供程序实现时,SyncFactory
实例将提供给断开连接的RowSet
对象的默认提供程序。
该同步提供程序使用乐观并发模型,假设在数据库中访问相同数据的用户之间将存在很少的冲突。 它避免使用锁; 而是在尝试同步RowSet
对象和数据源之前检查是否存在冲突。 如果有冲突,它什么都不做,这意味着对RowSet
对象的更改不会持久RowSet
到数据源。 -
RIXMLProvider
可与WebRowSet
对象一起使用的同步提供程序,该对象是可以以XML格式编写或从XML格式读取的行。RIXMLProvider
实现不会检查冲突,只需将WebRowSet
对象中的任何更新数据写入基础数据源。WebRowSet
对象在处理XML数据时使用此提供程序。
SyncProvider
实现与参考实现捆绑在一起,这使得它们始终可用于RowSet
实现。
SyncProvider
实现使自己可以通过注册SyncFactory
单例。
当一个RowSet
对象请求一个提供者时,通过在构造函数中指定它或作为CachedRowSet
方法setSyncProvider
的参数, SyncFactory
单例检查以查看请求的提供者是否已经注册。
如果它有, SyncFactory
创建一个实例,并将其传递给请求的RowSet
对象。
如果指定的SyncProvider
实现尚未注册,则SyncFactory
单SyncFactory
导致抛出SyncFactoryException
对象。
如果没有指定提供者,则SyncFactory
单例将创建默认提供程序实现的实例RIOptimisticProvider
,并将其传递给请求的RowSet
对象。
如果一个WebRowSet
对象在其构造函数中未指定提供者,那么SyncFactory
将给它一个RIOptimisticProvider
的实例。 但是,实现了WebRowSet
的构造函数来将提供程序设置为RIXMLProvider
,它以XML格式读写RowSet
对象。
有关详细信息,请参阅SyncProvider类规范。
供应商可以利用任何一个可能的同步级别来开发一个SyncProvider
实现,从而为RowSet
对象提供同步机制的选择。
2.0 Service Provider Interface Architecture
2.1概述 服务提供商接口提供可插拔机制,通过该机制可以注册SyncProvider
实现,然后在需要时生成。 SyncFactory
采用的延迟引用机制通过SyncFactory
创建实例SyncFactory
限制不必要的资源消耗,直到被断开的RowSet
对象需要。 SyncFactory
类还提供了一个标准API来配置可能由特定的SyncProvider
实现提供的日志记录选项和流。
2.2注册SyncFactory
第三方SyncProvider
实施必须与注册SyncFactory
为了断开连接RowSet
对象获取它,从而使用其javax.sql.RowSetReader
个javax.sql.RowSetWriter
实现。 以下注册机制适用于所有SyncProvider
实现:
- 系统属性 - 在命令行中设置的属性。 这些属性是在运行时设置的,并且每次调用Java应用程序时都将应用于系统范围。 详见"Related Documentation"相关资料。
- 属性文件 - 在标准属性文件中指定的属性。 这可以使用系统属性或通过修改位于平台运行时的标准属性文件来指定。 该技术的参考实现包括可编辑的标准属性文件,以添加其他
SyncProvider
对象。 - JNDI上下文 - 可以在JNDI上下文中注册可用的提供者。
SyncFactory
将尝试加载绑定到上下文的SyncProvider
对象,并将其注册到工厂。 必须将此上下文提供给SyncFactory
才能正常运行的机制。
有关如何指定属性文件中的系统属性或属性以及如何配置JNDI上下文的详细信息,请参见SyncFactory
类描述。
2.3 SyncFactory Provider实例生成策略
如果提供程序已正确注册,则SyncFactory
生成请求的SyncProvider
对象。 当使用指定的SyncProvider
实现来实例化断开连接的RowSet
对象时,或者在运行时使用替代的SyncProvider
对象重新配置,则遵守以下策略。
- 如果
SyncProvider
指定对象和SyncFactory
没有提及供应商,一个SyncFactoryException
被抛出。 - 如果指定了一个
SyncProvider
对象,并且SyncFactory
包含对提供程序的引用,则提供请求的提供程序。 - 如果没有指定
SyncProvider
对象,则提供参考实现提供者RIOptimisticProvider
。
这些政策在SyncFactory
课程中有更详细的探讨 。
3.0 SyncProvider Implementer's Guide
3.1要求 柔顺SyncProvider
实现,它是完全可插入到SyncFactory
必须扩展和实施中的所有抽象方法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_MODIFIED
和GRADE_LOCK_WHEN_LOADED
等级允许断开连接的RowSet
对象对锁定程度进行细粒度控制。
- DATASOURCE_NO_LOCK - 始发数据源上没有锁。 这是所有
SyncProvider
实现的默认锁定设置,除非由RowSet
对象另有指示。 - DATASOURCE_ROW_LOCK - 锁被放置在用于填充
RowSet
对象的原始SQL查询所触摸的行上。 - DATASOURCE_TABLE_LOCK - 被用于填充
RowSet
对象的查询所触及的所有表上都放置一个锁。 - DATASOURCE_DB_LOCK在
RowSet
对象使用的整个数据源上放置一个锁。
3.4可更新视图
可以使用来自SQL VIEW
数据填充RowSet
对象。 以下常量指示SyncProvider
对象是否可以更新派生VIEW
的表或表中的数据。
- UPDATABLE_VIEW_SYNC表示一个
SyncProvider
实现支持同步到VIEW
用于填充RowSet
对象的SQLVIEW
的表或表。 - NONUPDATABLE_VIEW_SYNC表示一个
SyncProvider
实现不支持同步从该SQL表或表VIEW
用于填充RowSet
对象导出。
3.5使用SyncProvider
分级和锁定
在下面的示例中,参考CachedRowSetImpl
实现通过调用setSyncProvider
方法重新配置其当前的SyncProvider
对象。
CachedRowSetImpl crs = new CachedRowSetImpl();
crs.setSyncProvider("com.foo.bar.HASyncProvider");
应用程序可以检索由断开连接的SyncProvider
对象当前正在使用的RowSet
对象。
它还可以检索提供者实现的同步级别和当前使用的锁定程度。
此外,应用程序具有设置要使用的锁定程度的灵活性,这可以增加成功同步的可能性。
这些操作显示在以下代码片段中。
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 Resolving Synchronization Conflicts
接口SyncResolver
提供了一种应用程序手动决定冲突发生时该做什么的一种方式。
当CachedRowSet
方法acceptChanges
完成并检测到一个或多个冲突时,它将抛出一个SyncProviderException
对象。
应用程序可以捕获异常,并通过调用方法SyncProviderException.getSyncResolver()
检索SyncResolver
对象。
一个SyncResolver
对象,它是一种特殊类型的CachedRowSet
对象或JdbcRowSet
对象,已实现了SyncResolver
接口,逐行检查冲突。 它是复制RowSet
对象被同步,除了它只包含来自数据源的数据导致冲突。 所有其他列值都设置为null
。 要从一个冲突值导航到另一个冲突值,一个SyncResolver
对象提供了方法nextConflict
和previousConflict
。
SyncResolver
接口还提供了以下方法:
- 了解冲突是否涉及更新,删除或插入
- 获取导致冲突的数据源中的值
- 如果需要更改,请设置应该在数据源中的值,如果需要更改,则设置应该在
RowSet
对象中的值
当调用CachedRowSet
方法acceptChanges
,它委托给RowSet
对象的SyncProvider
对象。 如何实现SyncProvider
对象提供的作者如何确定检查冲突的级别(等级)。 完成所有检查冲突并完成一个或多个冲突后,方法acceptChanges
将抛出一个SyncProviderException
对象。 应用程序可以捕获异常并使用它来获取一个SyncResolver
对象。
然后,应用程序可以使用SyncResolver
方法获取有关每个冲突的信息,并决定要执行的操作。 如果应用程序逻辑或用户决定RowSet
对象中的值应该是持久的,应用程序或用户可以使用它来覆盖数据源值。
对SyncResolver
界面的评论有更多的细节。
5.0 Related Specifications
6.0 Related Documentation
-
接口摘要 接口 描述 SyncResolver 定义一个框架,允许应用程序使用手动决策树来决定在发生同步冲突时应该做什么。TransactionalWriter 一个专门的界面,有助于扩展标准的SyncProvider
抽象类,使其具有更细粒度的事务控制。XmlReader 一个专门的界面,有助于扩展SyncProvider
XML定向同步提供程序的抽象类。XmlWriter 一个专门的界面,有助于扩展SyncProvider
XML定向同步提供程序的抽象类。 -
类摘要 Class 描述 SyncFactory 服务提供者接口(SPI)机制,生成SyncProvider
实例,由断开的RowSet
对象使用。SyncProvider 同步机制,为断开连接的RowSet
对象提供读写器功能。 -
异常摘要 异常 描述 SyncFactoryException 表示出现SyncFactory
机制的错误。SyncProviderException 表示SyncProvider
机制出现错误。