接口 | 描述 |
---|---|
SyncResolver |
定义一个框架,允许应用程序使用手动决策树来决定在发生同步冲突时应该做什么。
|
TransactionalWriter |
一个专门的界面,便于扩展标准的
SyncProvider 抽象类,使其具有更细粒度的事务控制。
|
XmlReader |
一个专门的界面,有助于扩展SyncProvider XML定向同步提供
SyncProvider 抽象类。
|
XmlWriter |
一种专门的界面,有助于扩展面向XML的同步提供程序的
SyncProvider 抽象类。
|
类 | 描述 |
---|---|
SyncFactory |
服务提供者接口(SPI)机制,生成
SyncProvider 实例,由断开的
RowSet 对象使用。
|
SyncProvider |
同步机制为断开
RowSet 对象提供读写器功能。
|
异常 | 描述 |
---|---|
SyncFactoryException |
表示有错误
SyncFactory 机制。
|
SyncProviderException |
表示与错误
SyncProvider 机制。
|
jdbc@sun.com
将其实现包含在JDBC网页上,列出可用的SyncProvider
jdbc@sun.com
。
这样做有助于使开发人员了解实施。
为了能够为RowSet
的对象使用一个实现,供应商必须与注册它SyncFactory
单。
(有关注册过程的完整说明和要使用的命名约定,请参阅SyncProvider
的类注释。)
The following classes and interfaces make up the javax.sql.rowset.spi
package:
SyncFactory
SyncProvider
SyncFactoryException
SyncProviderException
SyncResolver
XmlReader
XmlWriter
TransactionalWriter
javax.sql
package, are also part of the SPI:
RowSetReader
RowSetWriter
A SyncProvider
implementation provides a disconnected RowSet
object with the mechanisms for reading data into it and for writing data that has been modified in it back to the underlying data source. A reader, a RowSetReader
or XMLReader
object, reads data into a RowSet
object when the CachedRowSet
methods execute
or populate
are called. A writer, a RowSetWriter
or XMLWriter
object, writes changes back to the underlying data source when the CachedRowSet
method acceptChanges
is called.
The process of writing changes in a RowSet
object to its data source is known as synchronization. The SyncProvider
implementation that a RowSet
object is using determines the level of synchronization that the RowSet
object's writer uses. The various levels of synchronization are referred to as grades.
The lower grades of synchronization are known as optimistic concurrency levels because they optimistically assume that there will be no conflicts or very few conflicts. A conflict exists when the same data modified in the RowSet
object has also been modified in the data source. Using the optimistic concurrency model means that if there is a conflict, modifications to either the data source or the RowSet
object will be lost.
Higher grades of synchronization are called pessimistic because they assume that others will be accessing the data source and making modifications. These grades set varying levels of locks to increase the chances that no conflicts occur.
The lowest level of synchronization is simply writing any changes made to the RowSet
object to its underlying data source. The writer does nothing to check for conflicts. If there is a conflict and the data source values are overwritten, the changes other parties have made by to the data source are lost.
The RIXMLProvider
implementation uses the lowest level of synchronization and just writes RowSet
changes to the data source. This is true because typically XML data sources do not enable transaction techniques for maintaining the integrity of data. However, specific standards groups have considered offering XML-based synchronization. For details, see
http://www.syncml.org
对于下一个级别,作者检查是否有任何冲突,如果有的话,它不会对数据源写任何东西。 这种并发级别的问题是,如果另一方已经修改了数据源中的对应数据,因为RowSet
对象获得了其数据,则对RowSet
对象所做的更改将丢失。 RIOptimisticProvider
实现使用这种级别的同步。
在较高级别的同步,称为悲观并发,作者采取措施通过设置锁来避免冲突。 设置锁可以从设置单个行的锁定到在表或整个数据源上设置锁定而有所不同。 因此,同步级别是用户同时访问数据源的能力与作者将数据保持在RowSet
对象及其数据源同步的能力之间的折衷。
这是所有断开的要求RowSet
对象( CachedRowSet
, FilteredRowSet
, JoinRowSet
和WebRowSet
对象)获得其SyncProvider
从对象SyncFactory
机制。
参考实现(RI)提供了两个同步提供程序。
SyncFactory
实例在未指定提供程序实现时将提供给断开RowSet
对象的默认提供程序。 RowSet
对象和数据源之前检查是否存在冲突。 如果存在冲突,则不执行任何操作,这意味着RowSet
对象的更改不会持久保留到数据源。 WebRowSet
对象一起使用的同步提供程序,该对象是可以用XML格式编写或从XML格式读取的行集。 RIXMLProvider
实现不会检查冲突,只需将WebRowSet
对象中的任何更新的数据写入底层数据源。 WebRowSet
对象在处理XML数据时使用此提供程序。 SyncProvider
实现与SyncProvider
实现捆绑在一起,这使得它们始终可用于RowSet
实现。
SyncProvider
实现使自己可以通过注册SyncFactory
单身。
当一个RowSet
对象请求一个提供者时,通过在构造函数中指定它或CachedRowSet
方法setSyncProvider
的参数, SyncFactory
单例检查以查看请求的提供者是否已经注册。
如果它有, SyncFactory
创建一个实例,并将其传递给请求的RowSet
对象。
如果指定的SyncProvider
实现尚未注册,则SyncFactory
单例会导致抛出SyncFactoryException
对象。
如果没有指定提供者,SyncFactory SyncFactory
例将创建默认提供程序实现的实例RIOptimisticProvider
,并将其传递给请求的RowSet
对象。
如果一个WebRowSet
对象在其WebRowSet
函数中没有指定提供者,则SyncFactory
将给它一个RIOptimisticProvider
的实例。 然而,WebRowSet的WebRowSet
被实现以将提供者设置为RIXMLProvider
,其以XML格式读取和写入RowSet
对象。
有关详细信息,请参阅SyncProvider类规范。
供应商可以开发一个SyncProvider实现与同步的可能级别中的任何一个,从而使RowSet
对象的同步机制的选择。 供应商可以通过向甲骨文公司注册完全合格的类名,从而实现其可用性,方法是: jdbc@sun.com
。 以下进一步详细讨论该过程。
The Service Provider Interface provides a pluggable mechanism by which SyncProvider
implementations can be registered and then generated when required. The lazy reference mechanism employed by the SyncFactory
limits unnecessary resource consumption by not creating an instance until it is required by a disconnected RowSet
object. The SyncFactory
class also provides a standard API to configure logging options and streams that may be provided by a particular SyncProvider
implementation.
2.2 Registering with the SyncFactory
A third party SyncProvider
implementation must be registered with the SyncFactory
in order for a disconnected RowSet
object to obtain it and thereby use its javax.sql.RowSetReader
and javax.sql.RowSetWriter
implementations. The following registration mechanisms are available to all SyncProvider
implementations:
SyncProvider
objects.
SyncFactory
for the mechanism to function correctly. 有关如何指定属性文件中的系统属性或属性以及如何配置JNDI上下文的详细信息,请参见SyncFactory
类描述。
2.3 SyncFactory Provider实例生成策略
SyncFactory
如果提供程序已SyncFactory
注册,则生成请求的SyncProvider
对象。 当断开连接的RowSet
对象使用指定的SyncProvider SyncProvider
实例化或在运行时使用替代的SyncProvider
对象重新SyncProvider
时,将遵守SyncProvider
。
SyncProvider
指定对象和SyncFactory
没有提及供应商,一个SyncFactoryException
被抛出。 SyncProvider
对象,并且SyncFactory
包含对提供程序的引用,则提供所请求的提供程序。 SyncProvider
对象,则提供参考实现提供者RIOptimisticProvider
。 这些政策在SyncFactory
课程中有更详细的探讨 。
A compliant SyncProvider
implementation that is fully pluggable into the SyncFactory
must extend and implement all abstract methods in the SyncProvider
class. In addition, an implementation must determine the grade, locking and updatable view capabilities defined in the SyncProvider
class definition. One or more of the SyncProvider
description criteria must be supported. It is expected that vendor implementations will offer a range of grade, locking, and updatable view capabilities.
此外, SyncProvider
命名约定必须遵循SyncProvider
类描述中的详细说明。
3.2年级
JSR 114定义了一组等级来描述同步的质量,一个SyncProvider
对象可以提供一个断开RowSet
对象RowSet
。 这些等级从最低服务质量列为最高。
SyncProvider
实现返回此等级将简单的写在改变任何数据RowSet
对象的基础数据源,覆盖不管是存在的。 没有尝试将原始值与当前值进行比较,以查看是否存在冲突。 RIXMLProvider
是用这个档次实现的。 SyncProvider
实现返回此等级将检查行已经过去的同步和正在进行的当前同步之间更改冲突。 已修改的始发数据源中的任何更改都不会反映在断开RowSet
对象中。 如果没有冲突, RowSet
对象中的更改将被写入数据源。 如果有冲突,则不会改变。 RIOptimisticProvider
实现使用这个等级。 SyncProvider
实现返回此等级将检查所有的行,包括那些没有在断开更改的行RowSet
对象。 以这种方式,当同步完成成功时,底层数据源中对行的任何更改将反映在断开RowSet
对象中。 SyncProvider
此等级的SyncProvider实现将锁定与RowSet
对象中正在更改的行对应的始发数据源中的行,以减少其他进程修改数据源中相同数据的可能性。 SyncProvider
执行返回此等级将锁定受用于填充原始查询整个视图和/或表RowSet
对象。 3.3锁
JSR 114定义了一组常量,它们指定是否将任何锁放置在RowSet
对象的基础数据源上,如果是这样,则在其上放置锁定的构造。 这些锁将保留在数据源上,而RowSet
对象与数据源断开连接。
这些常数应该被认为是等级常数的补充。 大多数成绩设置的默认设置要求当RowSet
对象与其数据源断开连接时,不会保留数据源锁定。 等级GRADE_LOCK_WHEN_MODIFIED
和GRADE_LOCK_WHEN_LOADED
允许断开的RowSet
对象对锁定程度进行细粒度控制。
SyncProvider
实现的默认锁定设置,除非RowSet
对象另有指示。 RowSet
对象的原始SQL查询所触摸的行上。 RowSet
对象的查询所触及的所有表上都放置一个锁。 RowSet
对象使用的整个数据源上放置一个锁。 3.4可更新视图
可以使用来自SQL VIEW
数据RowSet
对象。 以下常量指示是否SyncProvider
对象可以更新表中或从该表中的数据VIEW
推导。
SyncProvider
实现支持同步到VIEW
用于填充RowSet
对象的SQL VIEW
表的表。 SyncProvider
实现不支持同步从该SQL表或表VIEW
用于填充RowSet
对象导出。 3.5使用SyncProvider
分级和锁定
在下面的示例中,参考CachedRowSetImpl实现通过调用setSyncProvider方法重新配置其当前的SyncProvider对象。
CachedRowSetImpl crs = new CachedRowSetImpl();
crs.setSyncProvider("com.foo.bar.HASyncProvider");
一个应用程序可以检索一个断开的RowSet对象当前正在使用的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
类确定的名单SyncProvider
当前与注册的实现SyncFactory
。
Enumeration e = SyncFactory.getRegisteredProviders();
SyncResolver
provides a way for an application to decide manually what to do when a conflict occurs. When the CachedRowSet
method acceptChanges
finishes and has detected one or more conflicts, it throws a SyncProviderException
object. An application can catch the exception and have it retrieve a SyncResolver
object by calling the method SyncProviderException.getSyncResolver()
. A SyncResolver
object, which is a special kind of CachedRowSet
object or a JdbcRowSet
object that has implemented the SyncResolver
interface, examines the conflicts row by row. It is a duplicate of the RowSet
object being synchronized except that it contains only the data from the data source this is causing a conflict. All of the other column values are set to null
. To navigate from one conflict value to another, a SyncResolver
object provides the methods nextConflict
and previousConflict
.
The SyncResolver
interface also provides methods for doing the following:
RowSet
object if it needs to be changed When the CachedRowSet
method acceptChanges
is called, it delegates to the RowSet
object's SyncProvider
object. How the writer provided by that SyncProvider
object is implemented determines what level (grade) of checking for conflicts will be done. After all checking for conflicts is completed and one or more conflicts has been found, the method acceptChanges
throws a SyncProviderException
object. The application can catch the exception and use it to obtain a SyncResolver
object.
The application can then use SyncResolver
methods to get information about each conflict and decide what to do. If the application logic or the user decides that a value in the RowSet
object should be the one to persist, the application or user can overwrite the data source value with it.
The comment for the SyncResolver
interface has more detail.