Package javax.sql.rowset.spi
RowSet object to use an implementation, the vendor must register
 it with the SyncFactory singleton. (See the class comment for
 SyncProvider for a full explanation of the registration process and
 the naming convention to be used.)
 Table of Contents
- 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
 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.
 
 For the next level up, the
 writer checks to see if there are any conflicts, and if there are,
 it does not write anything to the data source.  The problem with this concurrency
 level is that if another party has modified the corresponding data in the data source
 since the RowSet object got its data,
 the changes made to the RowSet object are lost. The
 RIOptimisticProvider implementation uses this level of synchronization.
 
 At higher levels of synchronization, referred to as pessimistic concurrency,
 the writer take steps to avoid conflicts by setting locks. Setting locks
 can vary from setting a lock on a single row to setting a lock on a table
 or the entire data source. The level of synchronization is therefore a tradeoff
 between the ability of users to access the data source concurrently and the  ability
 of the writer to keep the data in the RowSet object and its data source
 synchronized.
 
 It is a requirement that all disconnected RowSet objects
 (CachedRowSet, FilteredRowSet, JoinRowSet,
 and WebRowSet objects) obtain their SyncProvider objects
 from the SyncFactory mechanism.
 
The reference implementation (RI) provides two synchronization providers.
- RIOptimisticProvider
 The default provider that the- SyncFactoryinstance will supply to a disconnected- RowSetobject when no provider implementation is specified.
 This synchronization provider uses an optimistic concurrency model, assuming that there will be few conflicts among users who are accessing the same data in a database. It avoids using locks; rather, it checks to see if there is a conflict before trying to synchronize the- RowSetobject and the data source. If there is a conflict, it does nothing, meaning that changes to the- RowSetobject are not persisted to the data source.
- RIXMLProvider
 A synchronization provider that can be used with a- WebRowSetobject, which is a rowset that can be written in XML format or read from XML format. The- RIXMLProviderimplementation does no checking at all for conflicts and simply writes any updated data in the- WebRowSetobject to the underlying data source.- WebRowSetobjects use this provider when they are dealing with XML data.
SyncProvider implementations
  are bundled with the reference implementation, which makes them always available to
  RowSet implementations.
  SyncProvider implementations make themselves available by being
  registered with the SyncFactory singleton.  When a RowSet
  object requests a provider, by specifying it in the constructor or as an argument to the
  CachedRowSet method setSyncProvider,
  the SyncFactory singleton
  checks to see if the requested provider has been registered with it.
  If it has, the SyncFactory creates an instance of it and passes it to the
  requesting RowSet object.
  If the SyncProvider implementation that is specified has not been registered,
  the SyncFactory singleton causes a SyncFactoryException object
  to be thrown.  If no provider is specified,
  the SyncFactory singleton will create an instance of the default
  provider implementation, RIOptimisticProvider,
  and pass it to the requesting RowSet object.
 
 If a WebRowSet object does not specify a provider in its constructor, the
 SyncFactory will give it an instance of RIOptimisticProvider.
 However, the constructor for WebRowSet is implemented to set the provider
 to the RIXMLProvider, which reads and writes a RowSet object
  in XML format.
  
See the SyncProvider class specification for further details.
 Vendors may develop a SyncProvider implementation with any one of the possible
 levels of synchronization, thus giving RowSet objects a choice of
 synchronization mechanisms.
 
2.0 Service Provider Interface Architecture
2.1 Overview
 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:
 
- System properties - Properties set at the command line. These properties are set at run time and apply system-wide per invocation of the Java application. See the section "Related Documentation" further related information.
- Property Files - Properties specified in a standard property file.
 This can be specified using a System Property or by modifying a standard
 property file located in the platform run-time. The
 reference implementation of this technology includes a standard property
 file than can be edited to add additional SyncProviderobjects.
- JNDI Context - Available providers can be registered on a JNDI
 context. The SyncFactorywill attempt to loadSyncProviderobjects bound to the context and register them with the factory. This context must be supplied to theSyncFactoryfor the mechanism to function correctly.
 Details on how to specify the system properties or properties in a property file
 and how to configure the JNDI Context are explained in detail in the
 SyncFactory class description.
 
2.3 SyncFactory Provider Instance Generation Policies
 The SyncFactory generates a requested SyncProvider
 object if the provider has been correctly registered.  The
 following policies are adhered to when either a disconnected RowSet object
 is instantiated with a specified SyncProvider implementation or is
 reconfigured at runtime with an alternative SyncProvider object.
 
-  If a SyncProviderobject is specified and theSyncFactorycontains no reference to the provider, aSyncFactoryExceptionis thrown.
-  If a SyncProviderobject is specified and theSyncFactorycontains a reference to the provider, the requested provider is supplied.
-  If no SyncProviderobject is specified, the reference implementation providerRIOptimisticProvideris supplied.
 These policies are explored in more detail in the 
 SyncFactory class.
 
3.0 SyncProvider Implementer's Guide
3.1 Requirements
 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.
 
 Furthermore, the SyncProvider naming convention must be followed as
 detailed in the SyncProvider class
 description.
 
3.2 Grades
 JSR 114 defines a set of grades to describe the quality of synchronization
 a SyncProvider object can offer a disconnected RowSet
 object. These grades are listed from the lowest quality of service to the highest.
 
- GRADE_NONE - No synchronization with the originating data source is
 provided. A SyncProviderimplementation returning this grade will simply attempt to write any data that has changed in theRowSetobject to the underlying data source, overwriting whatever is there. No attempt is made to compare original values with current values to see if there is a conflict. TheRIXMLProvideris implemented with this grade.
- GRADE_CHECK_MODIFIED_AT_COMMIT - A low grade of optimistic synchronization.
 A SyncProviderimplementation returning this grade will check for conflicts in rows that have changed between the last synchronization and the current synchronization under way. Any changes in the originating data source that have been modified will not be reflected in the disconnectedRowSetobject. If there are no conflicts, changes in theRowSetobject will be written to the data source. If there are conflicts, no changes are written. TheRIOptimisticProviderimplementation uses this grade.
- GRADE_CHECK_ALL_AT_COMMIT - A high grade of optimistic synchronization.
 A SyncProviderimplementation returning this grade will check all rows, including rows that have not changed in the disconnectedRowSetobject. In this way, any changes to rows in the underlying data source will be reflected in the disconnectedRowSetobject when the synchronization finishes successfully.
- GRADE_LOCK_WHEN_MODIFIED - A pessimistic grade of synchronization.
 SyncProviderimplementations returning this grade will lock the row in the originating data source that corresponds to the row being changed in theRowSetobject to reduce the possibility of other processes modifying the same data in the data source.
- GRADE_LOCK_WHEN_LOADED - A higher pessimistic synchronization grade.
 A SyncProviderimplementation returning this grade will lock the entire view and/or table affected by the original query used to populate aRowSetobject.
3.3 Locks
 JSR 114 defines a set of constants that specify whether any locks have been
 placed on a RowSet object's underlying data source and, if so,
 on which constructs the locks are placed.  These locks will remain on the data
 source while the RowSet object is disconnected from the data source.
 
 These constants should be considered complementary to the
 grade constants. The default setting for the majority of grade settings requires
 that no data source locks remain when a RowSet object is disconnected
 from its data source.
 The grades GRADE_LOCK_WHEN_MODIFIED and
 GRADE_LOCK_WHEN_LOADED allow a disconnected RowSet object
 to have a fine-grained control over the degree of locking.
 
- DATASOURCE_NO_LOCK - No locks remain on the originating data source.
 This is the default lock setting for all SyncProviderimplementations unless otherwise directed by aRowSetobject.
- DATASOURCE_ROW_LOCK - A lock is placed on the rows that are touched by
 the original SQL query used to populate the RowSetobject.
- DATASOURCE_TABLE_LOCK - A lock is placed on all tables that are touched
 by the query that was used to populate the RowSetobject.
- DATASOURCE_DB_LOCK
 A lock is placed on the entire data source that is used by the RowSetobject.
3.4 Updatable Views
 A RowSet object may be populated with data from an SQL VIEW.
 The following constants indicate whether a SyncProvider object can
 update data in the table or tables from which the VIEW was derived.
 
- UPDATABLE_VIEW_SYNC
 Indicates that a SyncProviderimplementation supports synchronization to the table or tables from which the SQLVIEWused to populate aRowSetobject is derived.
- NONUPDATABLE_VIEW_SYNC
 Indicates that a SyncProviderimplementation does not support synchronization to the table or tables from which the SQLVIEWused to populate aRowSetobject is derived.
 3.5 Usage of SyncProvider Grading and Locking
 
 In the example below, the reference CachedRowSetImpl implementation
 reconfigures its current SyncProvider object by calling the
 setSyncProvider method.
 
   CachedRowSetImpl crs = new CachedRowSetImpl();
   crs.setSyncProvider("com.foo.bar.HASyncProvider");
 
   An application can retrieve the SyncProvider object currently in use
 by a disconnected RowSet object. It can also retrieve the
 grade of synchronization with which the provider was implemented and the degree of
 locking currently in use.  In addition, an application has the flexibility to set
 the degree of locking to be used, which can increase the possibilities for successful
 synchronization.  These operation are shown in the following code fragment.
 
   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.getDataSourceLock() {
      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;
 
    It is also possible using the static utility method in the
 SyncFactory class to determine the list of SyncProvider
 implementations currently registered with the SyncFactory.
 
       Enumeration e = SyncFactory.getRegisteredProviders();
 
 4.0 Resolving Synchronization Conflicts
The interfaceSyncResolver 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:
 
- finding out whether the conflict involved an update, a delete, or an insert
- getting the value in the data source that caused the conflict
- setting the value that should be in the data source if it needs to be changed
      or setting the value that should be in the RowSetobject 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.
 
5.0 Related Specifications
6.0 Related Documentation
- 
Interface Summary Interface Description SyncResolver Defines a framework that allows applications to use a manual decision tree to decide what should be done when a synchronization conflict occurs.TransactionalWriter A specialized interface that facilitates an extension of the standardSyncProviderabstract class so that it has finer grained transaction control.XmlReader A specialized interface that facilitates an extension of theSyncProviderabstract class for XML orientated synchronization providers.XmlWriter A specialized interface that facilitates an extension of theSyncProviderabstract class for XML orientated synchronization providers.
- 
Class Summary Class Description SyncFactory The Service Provider Interface (SPI) mechanism that generatesSyncProviderinstances to be used by disconnectedRowSetobjects.SyncProvider The synchronization mechanism that provides reader/writer capabilities for disconnectedRowSetobjects.
- 
Exception Summary Exception Description SyncFactoryException Indicates an error withSyncFactorymechanism.SyncProviderException Indicates an error with theSyncProvidermechanism.