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
对象,该对象具有将数据读入其中以及将已在其中修改的数据写回底层数据源的机制。 当CachedRowSet
方法execute
或populate
时,读取器 RowSetReader
或XMLReader
对象将数据读入RowSet
对象。 作家 , RowSetWriter
或XMLWriter
当对象,写入变回底层数据源CachedRowSet
方法acceptChanges
被调用。
将RowSet
对象中的更改写入其数据源的过程称为同步 。 所述SyncProvider
实现,一个RowSet
对象是使用判定同步的水平RowSet
对象的作者使用。 各种级别的同步称为等级 。
较低等级的同步被称为乐观并发级别,因为它们乐观地认为不会发生冲突或冲突很少。 当在数据源中修改了RowSet
对象中修改的相同数据时,存在冲突。 使用乐观并发模型意味着如果存在冲突,将丢失对数据源或RowSet
对象的修改。
更高级别的同步被称为悲观,因为他们认为其他人将访问数据源并进行修改。 这些等级设置不同级别的锁定以增加不发生冲突的机会。
最低级别的同步只是将对RowSet
对象所做的任何更改写入其基础数据源。 作者没有做任何事情来检查冲突。 如果存在冲突并且数据源值被覆盖,则其他方对数据源所做的更改将丢失。
RIXMLProvider
实现使用最低级别的同步,只是将RowSet
更改写入数据源。
对于下一级别,编写器检查是否存在任何冲突,如果存在冲突,则不会向数据源写入任何内容。 此并发级别的问题是,如果另一方修改了数据源中的相应数据,因为RowSet
对象获取了其数据,则对RowSet
对象所做的更改将丢失。 RIOptimisticProvider
实现使用此级别的同步。
在更高级别的同步(称为悲观并发)时,编写器通过设置锁来采取措施来避免冲突。 设置锁定可以从设置单个行上的锁定到设置表格锁定或整个数据源。 因此,同步级别是用户同时访问数据源的能力与写入器保持RowSet
对象中的数据及其数据源同步的能力之间的权衡。
这是所有断开的要求RowSet
对象( CachedRowSet
, FilteredRowSet
, JoinRowSet
和WebRowSet
对象)获得其SyncProvider
从对象SyncFactory
机制。
参考实现(RI)提供两个同步提供程序。
-
RIOptimisticProvider
在未指定提供程序实现时,SyncFactory
实例将向断开连接的RowSet
对象提供的默认提供程序。
此同步提供程序使用乐观并发模型,假设在访问数据库中的相同数据的用户之间几乎没有冲突。 它避免使用锁; 相反,它会在尝试同步RowSet
对象和数据源之前检查是否存在冲突。 如果存在冲突,则不执行任何操作,这意味着对RowSet
对象的更改不会持久保存到数据源。 -
RIXMLProvider
可与WebRowSet
对象一起使用的同步提供程序,该对象是可以XML格式编写或从XML格式读取的行集。RIXMLProvider
实现根本不检查冲突,只是将WebRowSet
对象中的任何更新数据写入基础数据源。WebRowSet
对象在处理XML数据时使用此提供程序。
SyncProvider
实现与参考实现捆绑在一起,这使得它们始终可用于RowSet
实现。
SyncProvider
实现通过向SyncFactory
singleton注册使其可用。
当RowSet
对象请求提供者时,通过在构造函数中指定它或者作为CachedRowSet
方法setSyncProvider
的参数, SyncFactory
单例检查以查看所请求的提供者是否已向其注册。
如果有,则SyncFactory
创建它的实例并将其传递给请求的RowSet
对象。
如果尚未注册指定的SyncProvider
实现,则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
使用的惰性引用机制通过在断开的RowSet
对象需要之前不创建实例SyncFactory
限制不必要的资源消耗。 SyncFactory
类还提供了一个标准API,用于配置特定SyncProvider
实现可能提供的日志记录选项和流。
2.2注册SyncFactory
必须向SyncFactory
注册第三方SyncProvider
实现,以便断开连接的RowSet
对象以获取它,从而使用其javax.sql.RowSetReader
和javax.sql.RowSetWriter
实现。 以下注册机制适用于所有SyncProvider
实施:
- 系统属性 - 在命令行中设置的属性。 这些属性在运行时设置,并在每次调用Java应用程序时应用于系统范围。 请参阅"Related Documentation"部分的更多相关信息。
- 属性文件 - 标准属性文件中指定的属性。 这可以使用系统属性或修改位于平台运行时的标准属性文件来指定。 此技术的参考实现包括一个标准属性文件,可以编辑以添加其他
SyncProvider
对象。 - JNDI上下文 - 可以在JNDI上下文中注册可用的提供程序。
SyncFactory
将尝试加载绑定到上下文的SyncProvider
对象并将其注册到工厂。 必须将此上下文提供给SyncFactory
才能使机制正常运行。
有关如何在属性文件中指定系统属性或属性以及如何配置JNDI上下文的详细信息,请参见SyncFactory
类说明。
2.3 SyncFactory提供程序实例生成策略
如果提供程序已正确注册, 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
将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
派生VIEW
的表中的数据。
- UPDATABLE_VIEW_SYNC指示
SyncProvider
实现支持与用于填充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
对象或实现了SyncResolver
接口的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 一个专门的接口,有助于为面向XML的同步提供程序扩展SyncProvider
抽象类。XmlWriter 一种专用接口,有助于扩展面向XML的同步提供程序的SyncProvider
抽象类。 -
类摘要 类 描述 SyncFactory 服务提供程序接口(SPI)机制,生成SyncProvider
实例,供断开连接的RowSet
对象使用。SyncProvider 为断开连接的RowSet
对象提供读取器/写入器功能的同步机制。 -
异常摘要 异常 描述 SyncFactoryException 表示SyncFactory
机制的错误。SyncProviderException 表示SyncProvider
机制出错。