jdk/src/share/classes/javax/sql/rowset/spi/package.html
changeset 2 90ce3da70b43
child 5506 202f599c92aa
equal deleted inserted replaced
0:fd16c54261b3 2:90ce3da70b43
       
     1 <!DOCTYPE doctype PUBLIC "-//w3c//dtd html 4.0 transitional//en">
       
     2 <html>
       
     3 <head>
       
     4                     
       
     5   <meta http-equiv="Content-Type"
       
     6  content="text/html; charset=iso-8859-1">
       
     7                     
       
     8   <meta name="GENERATOR"
       
     9  content="Mozilla/4.79 [en] (Windows NT 5.0; U) [Netscape]">
       
    10 <!--
       
    11 Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
       
    12 DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
    13 
       
    14 This code is free software; you can redistribute it and/or modify it
       
    15 under the terms of the GNU General Public License version 2 only, as
       
    16 published by the Free Software Foundation.  Sun designates this
       
    17 particular file as subject to the "Classpath" exception as provided
       
    18 by Sun in the LICENSE file that accompanied this code.
       
    19 
       
    20 This code is distributed in the hope that it will be useful, but WITHOUT
       
    21 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    22 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    23 version 2 for more details (a copy is included in the LICENSE file that
       
    24 accompanied this code).
       
    25 
       
    26 You should have received a copy of the GNU General Public License version
       
    27 2 along with this work; if not, write to the Free Software Foundation,
       
    28 Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    29 
       
    30 Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
       
    31 CA 95054 USA or visit www.sun.com if you need additional information or
       
    32 have any questions.
       
    33 -->
       
    34   <title>javax.sql.rowset.spi</title>
       
    35    
       
    36 </head>
       
    37   <body bgcolor="#ffffff">
       
    38 
       
    39 The standard classes and interfaces that a third party vendor has to
       
    40 use in its implementation of a synchronization provider. These classes and 
       
    41 interfaces are referred to as the Service Provider Interface (SPI). A vendor may 
       
    42 have its implementation included on the JDBC web page that lists available
       
    43 <code>SyncProvider</code> implementations by sending email to <code>jdbc@sun.com</code>.
       
    44 Doing this helps make developers aware of the implementation. To make it possible
       
    45 for a <code>RowSet</code> object to use an implementation, the vendor must register
       
    46 it with the <code>SyncFactory</code> singleton. (See the class comment for
       
    47 <code>SyncProvider</code> for a full explanation of the registration process and 
       
    48 the naming convention to be used.)
       
    49 <P>
       
    50 <h2>Table of Contents</h2>
       
    51 <ul>
       
    52 <li><a href="#pkgspec">1.0 Package Specification</a>
       
    53 <li><a href="#arch">2.0 Service Provider Architecture</a>
       
    54 <li><a href="#impl">3.0 Implementer's Guide</a>
       
    55 <li><a href="#resolving">4.0 Resolving Synchronization Conflicts</a>
       
    56 <li><a href="#relspec">5.0 Related Specifications</a>
       
    57 <li><a href="#reldocs">6.0 Related Documentation</a>
       
    58 </ul>
       
    59 
       
    60 <h3><a name="pkgspec">1.0 Package Specification</h3>
       
    61 <P>
       
    62 The following classes and interfaces make up the <code>javax.sql.rowset.spi</code>
       
    63 package:
       
    64 <UL>
       
    65   <LI><code>SyncFactory</code>
       
    66   <LI><code>SyncProvider</code>
       
    67   <LI><code>SyncFactoryException</code>
       
    68   <LI><code>SyncProviderException</code>
       
    69   <LI><code>SyncResolver</code>
       
    70   <LI><code>XmlReader</code>
       
    71   <LI><code>XmlWriter</code>
       
    72   <LI><code>TransactionalWriter</code>
       
    73 </UL>
       
    74 The following interfaces, in the <code>javax.sql</code> package, are also part of the SPI:
       
    75 <UL>
       
    76   <LI><code>RowSetReader</code>
       
    77   <LI><code>RowSetWriter</code>
       
    78 </UL>
       
    79 <P>
       
    80 A <code>SyncProvider</code> implementation provides a disconnected <code>RowSet</code>
       
    81 object with the mechanisms for reading data into it and for writing data that has been
       
    82 modified in it
       
    83 back to the underlying data source.  A <i>reader</i>, a <code>RowSetReader</code> or
       
    84 <code>XMLReader</code> object, reads data into a <code>RowSet</code> object when the 
       
    85 <code>CachedRowSet</code> methods <code>execute</code> or <code>populate</code> 
       
    86 are called.  A <i>writer</i>, a <code>RowSetWriter</code> or <code>XMLWriter</code>
       
    87 object, writes changes back to the underlying data source when the 
       
    88 <code>CachedRowSet</code> method <code>acceptChanges</code> is called.
       
    89 <P>
       
    90 The process of writing changes in a <code>RowSet</code> object to its data source
       
    91 is known as <i>synchronization</i>.  The <code>SyncProvider</code> implementation that a
       
    92 <code>RowSet</code> object is using determines the level of synchronization that the
       
    93 <code>RowSet</code> object's writer uses. The various levels of synchronization are
       
    94 referred to as <i>grades</i>.
       
    95 <P>
       
    96 The lower grades of synchronization are
       
    97 known as <i>optimistic</i> concurrency levels because they optimistically
       
    98 assume that there will be no conflicts or very few conflicts.  A conflict exists when
       
    99 the same data modified in the <code>RowSet</code> object has also been modified 
       
   100 in the data source. Using the optimistic concurrency model means that if there
       
   101 is a conflict, modifications to either the data source or the <code>RowSet</code> 
       
   102 object will be lost.
       
   103 <P>
       
   104 Higher grades of synchronization are called <i>pessimistic</i> because they assume
       
   105 that others will be accessing the data source and making modifications.  These
       
   106 grades set varying levels of locks to increase the chances that no conflicts
       
   107 occur.
       
   108 <P>
       
   109 The lowest level of synchronization is simply writing any changes made to the 
       
   110 <code>RowSet</code> object to its underlying data source.  The writer does
       
   111 nothing to check for conflicts. 
       
   112 If there is a conflict and the data
       
   113 source values are overwritten, the changes other parties have made by to the data
       
   114 source are lost. 
       
   115 <P>
       
   116 The <code>RIXMLProvider</code> implementation uses the lowest level 
       
   117 of synchronization and just writes <code>RowSet</code> changes to the data source.
       
   118 This is true because  typically XML data sources do not enable transaction
       
   119 techniques for maintaining the integrity of data. However, specific standards 
       
   120 groups have considered offering XML-based synchronization.  For details, see
       
   121 <PRE>
       
   122      <a href="http://www.syncml.org">http://www.syncml.org</a>
       
   123 </PRE>
       
   124 <P>
       
   125 For the the next level up, the
       
   126 writer checks to see if there are any conflicts, and if there are, 
       
   127 it does not write anything to the data source.  The problem with this concurrency
       
   128 level is that if another party has modified the corresponding data in the data source 
       
   129 since the <code>RowSet</code> object got its data,
       
   130 the changes made to the <code>RowSet</code> object are lost. The
       
   131 <code>RIOptimisticProvider</code> implementation uses this level of synchronization.
       
   132 <P>
       
   133 At higher levels of synchronization, referred to as pessimistic concurrency,
       
   134 the writer take steps to avoid conflicts by setting locks. Setting locks
       
   135 can vary from setting a lock on a single row to setting a lock on a table 
       
   136 or the entire data source. The level of synchronization is therefore a tradeoff 
       
   137 between the ability of users to access the data source concurrently and the  ability
       
   138 of the writer to keep the data in the <code>RowSet</code> object and its data source
       
   139 synchronized.
       
   140 <P>
       
   141 It is a requirement that all disconnected <code>RowSet</code> objects 
       
   142 (<code>CachedRowSet</code>, <code>FilteredRowSet</code>, <code>JoinRowSet</code>, 
       
   143 and <code>WebRowSet</code> objects) obtain their <code>SyncProvider</code> objects
       
   144 from the <code>SyncFactory</code> mechanism.  
       
   145 <P>
       
   146 The reference implementation (RI) provides two synchronization providers.
       
   147 	<UL>
       
   148        <LI><b><tt>RIOptimisticProvider</tt></b> <br>
       
   149            The default provider that the <code>SyncFactory</code> instance will
       
   150            supply to a disconnected <code>RowSet</code> object when no provider
       
   151            implementation is specified.<BR>
       
   152            This synchronization provider uses an optimistic concurrency model,
       
   153            assuming that there will be few conflicts among users 
       
   154            who are accessing the same data in a database.  It avoids
       
   155            using locks; rather, it checks to see if there is a conflict
       
   156            before trying to synchronize the <code>RowSet</code> object and the
       
   157            data source. If there is a conflict, it does nothing, meaning that
       
   158 		   changes to the <code>RowSet</code> object are not persisted to the data
       
   159            source.
       
   160        <LI><B><tt>RIXMLProvider</tt></B> <BR>
       
   161             A synchronization provider that can be used with a
       
   162             <code>WebRowSet</code> object, which is a rowset that can be written 
       
   163             in XML format or read from XML format. The 
       
   164             <code>RIXMLProvider</code> implementation does no checking at all for
       
   165             conflicts and simply writes any updated data in the
       
   166             <code>WebRowSet</code> object to the underlying data source.
       
   167             <code>WebRowSet</code> objects use this provider when they are 
       
   168             dealing with XML data.
       
   169 	</UL>
       
   170 
       
   171 These <code>SyncProvider</code> implementations
       
   172 are bundled with the reference implementation, which makes them always available to
       
   173 <code>RowSet</code> implementations. 
       
   174 <code>SyncProvider</code> implementations make themselves available by being
       
   175 registered with the <code>SyncFactory</code> singleton.  When a <code>RowSet</code> 
       
   176 object requests a provider, by specifying it in the constructor or as an argument to the
       
   177 <code>CachedRowSet</code> method <code>setSyncProvider</code>, 
       
   178 the <code>SyncFactory</code> singleton
       
   179 checks to see if the requested provider has been registered with it.
       
   180 If it has, the <code>SyncFactory</code> creates an instance of it and passes it to the
       
   181 requesting <code>RowSet</code> object.  
       
   182 If the <code>SyncProvider</code> implementation that is specified has not been registered,
       
   183 the <code>SyncFactory</code> singleton causes a <code>SyncFactoryException</code> object
       
   184 to be thrown.  If no provider is specified,
       
   185 the <code>SyncFactory</code> singleton will create an instance of the default
       
   186 provider implementation, <code>RIOptimisticProvider</code>,
       
   187 and pass it to the requesting <code>RowSet</code> object.
       
   188 
       
   189 <P>
       
   190 If a <code>WebRowSet</code> object does not specify a provider in its constructor, the
       
   191 <code>SyncFactory</code> will give it an instance of <code>RIOptimisticProvider</code>.
       
   192 However, the constructor for <code>WebRowSet</code> is implemented to set the provider 
       
   193 to the <code>RIXMLProvider</code>, which reads and writes a <code>RowSet</code> object
       
   194 in XML format.
       
   195 <P>
       
   196 See the <a href="SyncProvider.html">SyncProvider</a> class
       
   197 specification for further details.
       
   198 <p>
       
   199 Vendors may develop a <tt>SyncProvider</tt> implementation with any one of the possible
       
   200 levels of synchronization, thus giving <code>RowSet</code> objects a choice of
       
   201 synchronization mechanisms.  A vendor can make its implementation available by 
       
   202 registering the fully qualified class name with Sun Microsystems at 
       
   203 <code>jdbc@sun.com</code>. This process is discussed in further detail below. 
       
   204 <P>
       
   205 
       
   206 <a name="arch"><h3>2.0 Service Provider Interface Architecture</h3>
       
   207 <ul>
       
   208 <b>2.1 Overview</b>
       
   209 <p>
       
   210 The Service Provider Interface provides a pluggable mechanism by which
       
   211 <code>SyncProvider</code> implementations can be registered and then generated when
       
   212 required. The lazy reference mechanism employed by the <code>SyncFactory</code> limits
       
   213 unnecessary resource consumption by not creating an instance until it is 
       
   214 required by a disconnected
       
   215 <code>RowSet</code> object. The <code>SyncFactory</code> class also provides
       
   216 a standard API to configure logging options and streams that <b>may</b> be provided
       
   217 by a particular <code>SyncProvider</code> implementation.
       
   218 <p>
       
   219 <b>2.2 Registering with the <code>SyncFactory</code></b>
       
   220 <p>
       
   221 A third party <code>SyncProvider</code> implementation must be registered with the 
       
   222 <code>SyncFactory</code> in order for a disconnected <code>RowSet</code> object 
       
   223 to obtain it and thereby use its <code>javax.sql.RowSetReader</code> and 
       
   224 <code>javax.sql.RowSetWriter</code>
       
   225 implementations. The following registration mechanisms are available to all 
       
   226 <code>SyncProvider</code> implementations:
       
   227 <ul>
       
   228 <li><b>System properties</b> - Properties set at the command line. These
       
   229 properties are set at run time and apply system-wide per invocation of the Java
       
   230 application. See the section <a href="#reldocs">"Related Documentation"</a>
       
   231 further related information.
       
   232 <p>
       
   233 <li><b>Property Files</b> - Properties specified in a standard property file.
       
   234 This can be specified using a System Property or by modifying a standard
       
   235 property file located in the platform run-time. The
       
   236 reference implementation of this technology includes a standard property
       
   237 file than can be edited to add additional <code>SyncProvider</code> objects.
       
   238 <p> 
       
   239 <li><b>JNDI Context</b> - Available providers can be registered on a JNDI
       
   240 context. The <tt>SyncFactory</tt> will attempt to load <tt>SyncProvider</tt>
       
   241 objects bound to the context and register them with the factory. This
       
   242 context must be supplied to the <code>SyncFactory</code> for the mechanism to 
       
   243 function correctly.
       
   244 </ul>
       
   245 <p>
       
   246 Details on how to specify the system properties or properties in a property file
       
   247 and how to configure the JNDI Context are explained in detail in the
       
   248 <a href="SyncFactory.html"><code>SyncFactory</code></a> class description.
       
   249 <p>
       
   250 <b>2.3 SyncFactory Provider Instance Generation Policies</b>
       
   251 <p>
       
   252 The <code>SyncFactory</code> generates a requested <code>SyncProvider</code>
       
   253 object if the provider has been correctly registered.  The
       
   254 following policies are adhered to when either a disconnected <code>RowSet</code> object
       
   255 is instantiated with a specified <code>SyncProvider</code> implementation or is 
       
   256 reconfigured at runtime with an alternative <code>SyncProvider</code> object.
       
   257 <ul>
       
   258 <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
       
   259 contains <i>no</i> reference to the provider, a <code>SyncFactoryException</code> is 
       
   260 thrown.
       
   261 <p>
       
   262 <li> If a <code>SyncProvider</code> object is specified and the <code>SyncFactory</code>
       
   263 contains a reference to the provider, the requested provider is supplied.
       
   264 <p>
       
   265 <li> If no <code>SyncProvider</code> object is specified, the reference
       
   266 implementation provider <code>RIOptimisticProvider</code> is supplied.
       
   267 </ul>
       
   268 <p>
       
   269 These policies are explored in more detail in the <a href="SyncFactory.html">
       
   270 <code>SyncFactory</code></a> class.
       
   271 </ul>
       
   272 
       
   273 <li><a name="impl"><h3>3.0 SyncProvider Implementer's Guide</h3>
       
   274 <ul>
       
   275 <b>3.1 Requirements</b>
       
   276 <p>
       
   277 A compliant <code>SyncProvider</code> implementation that is fully pluggable
       
   278 into the <code>SyncFactory</code> <b>must</b> extend and implement all
       
   279 abstract methods in the <a href="SyncProvider.html"><code>SyncProvider</code></a>
       
   280 class. In addition, an implementation <b>must</b> determine the 
       
   281 grade, locking and updatable view capabilities defined in the
       
   282 <code>SyncProvider</code> class definition. One or more of the
       
   283 <code>SyncProvider</code> description criteria <b>must</b> be supported. It
       
   284 is expected that vendor implementations will offer a range of grade, locking, and
       
   285 updatable view capabilities.
       
   286 <p>
       
   287 Furthermore, the <code>SyncProvider</code> naming convention <b>must</b> be followed as
       
   288 detailed in the <a href="SyncProvider.html"><code>SyncProvider</code></a> class
       
   289 description.
       
   290 <p>
       
   291 <b>3.2 Grades</b>
       
   292 <p>
       
   293 JSR 114 defines a set of grades to describe the quality of synchronization
       
   294 a <code>SyncProvider</code> object can offer a disconnected <code>RowSet</code>
       
   295 object. These grades are listed from the lowest quality of service to the highest.
       
   296 <ul>
       
   297 <li><b>GRADE_NONE</b> - No synchronization with the originating data source is
       
   298 provided. A <code>SyncProvider</code> implementation returning this grade will simply
       
   299 attempt to write any data that has changed in the <code>RowSet</code> object to the
       
   300 underlying data source, overwriting whatever is there. No attempt is made to compare 
       
   301 original values with current values to see if there is a conflict. The 
       
   302 <code>RIXMLProvider</code> is implemented with this grade.
       
   303 <p>
       
   304 <li><b>GRADE_CHECK_MODIFIED_AT_COMMIT</b> - A low grade of optimistic synchronization.
       
   305 A <code>SyncProvider</code> implementation returning this grade
       
   306 will check for conflicts in rows that have changed between the last synchronization 
       
   307 and the current synchronization under way. Any changes in the originating data source
       
   308 that have been modified will not be reflected in the disconnected <code>RowSet</code>
       
   309 object. If there are no conflicts, changes in the <code>RowSet</code> object will be
       
   310 written to the data source. If there are conflicts, no changes are written.
       
   311 The <code>RIOptimisticProvider</code> implementation uses this grade.
       
   312 <p>
       
   313 <li><b>GRADE_CHECK_ALL_AT_COMMIT</b> - A high grade of optimistic synchronization.
       
   314 A <code>SyncProvider</code> implementation   returning this grade
       
   315 will check all rows, including rows that have not changed in the disconnected
       
   316 <code>RowSet</code> object. In this way, any changes to rows in the underlying
       
   317 data source will be reflected in the disconnected <code>RowSet</code> object
       
   318 when the synchronization finishes successfully.
       
   319 <p>
       
   320 <li><b>GRADE_LOCK_WHEN_MODIFIED</b> - A pessimistic grade of synchronization.
       
   321 <code>SyncProvider</code> implementations returning this grade will lock
       
   322 the row in the originating  data source that corresponds to the row being changed
       
   323 in the <code>RowSet</code> object to reduce the possibility of other
       
   324 processes modifying the same data in the data source.
       
   325 <p>
       
   326 <li><b>GRADE_LOCK_WHEN_LOADED</b> - A higher pessimistic synchronization grade.
       
   327 A <code>SyncProvider</code> implementation returning this grade will lock
       
   328 the entire view and/or  table affected by the original query used to
       
   329 populate a <code>RowSet</code> object.
       
   330 </ul>
       
   331 <p>
       
   332 <b>3.3 Locks</b>
       
   333 <p>
       
   334 JSR 114 defines a set of constants that specify whether any locks have been
       
   335 placed on a <code>RowSet</code> object's underlying data source and, if so,
       
   336 on which constructs the locks are placed.  These locks will remain on the data
       
   337 source while the <code>RowSet</code> object is disconnected from the data source.
       
   338 <P>
       
   339 These constants <b>should</b> be considered complementary to the 
       
   340 grade constants. The default setting for the majority of grade settings requires
       
   341 that no data source locks remain when a <code>RowSet</code> object is disconnected 
       
   342 from its data source.
       
   343 The grades <code>GRADE_LOCK_WHEN_MODIFIED</code> and
       
   344 <code>GRADE_LOCK_WHEN_LOADED</code> allow a disconnected <code>RowSet</code> object
       
   345 to have a fine-grained control over the degree of locking.
       
   346 <ul>
       
   347 <li><b>DATASOURCE_NO_LOCK</b> - No locks remain on the originating data source. 
       
   348 This is the default lock setting for all <code>SyncProvider</code> implementations 
       
   349 unless otherwise directed by a <code>RowSet</code> object.
       
   350 <p>
       
   351 <li><b>DATASOURCE_ROW_LOCK</b> - A lock is placed on the rows that are touched by
       
   352 the original SQL query used to populate the <code>RowSet</code> object.
       
   353 <p> 
       
   354 <li><b>DATASOURCE_TABLE_LOCK</b> - A lock is placed on all tables that are touched
       
   355 by the query that was used to populate the <code>RowSet</code> object.
       
   356 <p>
       
   357 <li><b>DATASOURCE_DB_LOCK</b>
       
   358 A lock is placed on the entire data source that is used by the <code>RowSet</code>
       
   359 object.
       
   360 </ul>
       
   361 <p>
       
   362 <b>3.4 Updatable Views</b>
       
   363 <p>
       
   364 A <code>RowSet</code> object may be populated with data from an SQL <code>VIEW</code>.
       
   365 The following constants indicate whether a <code>SyncProvider</code> object can
       
   366 update data in the table or tables from which the <code>VIEW</code> was derived.
       
   367 <ul>
       
   368 <li><b>UPDATABLE_VIEW_SYNC</b>
       
   369 Indicates that a <code>SyncProvider</code> implementation  supports synchronization
       
   370 to the table or tables from which the SQL <code>VIEW</code> used to populate  a
       
   371 a <code>RowSet</code> object is derived.
       
   372 <p>
       
   373 <li><b>NONUPDATABLE_VIEW_SYNC</b>
       
   374 Indicates that a <code>SyncProvider</code> implementation  does <b>not</b> support
       
   375 synchronization to the table or tables from which the SQL <code>VIEW</code> 
       
   376 used to populate  a <code>RowSet</code> object is derived.
       
   377 </ul>
       
   378 <p>
       
   379 <b>3.5 Usage of <code>SyncProvider</code> Grading and Locking</b>
       
   380 <p>
       
   381 In the example below, the reference <tt>CachedRowSetImpl</tt> implementation
       
   382 reconfigures its current <tt>SyncProvider</tt> object by calling the 
       
   383 <tt>setSyncProvider</tt> method.<br>
       
   384        
       
   385 <PRE>
       
   386     CachedRowSetImpl crs = new CachedRowSetImpl();
       
   387     crs.setSyncProvider("com.foo.bar.HASyncProvider");
       
   388 </PRE>
       
   389     An application can retrieve the <tt>SyncProvider</tt> object currently in use
       
   390 by a disconnected <code>RowSet</code> object. It can also retrieve the
       
   391 grade of synchronization with which the provider was implemented and the degree of
       
   392 locking currently in use.  In addition, an application has the flexibility to set
       
   393 the degree of locking to be used, which can increase the possibilities for successful
       
   394 synchronization.  These operation are shown in the following code fragment.
       
   395 <PRE>
       
   396     SyncProvider sync = crs.getSyncProvider();
       
   397 
       
   398     switch (sync.getProviderGrade()) {
       
   399     case: SyncProvider.GRADE_CHECK_ALL_AT_COMMIT
       
   400          //A high grade of optimistic synchronization
       
   401     break;
       
   402     case: SyncProvider.GRADE_CHECK_MODIFIED_AT_COMMIT 
       
   403          //A low grade of optimistic synchronization 
       
   404     break;
       
   405     case: SyncProvider.GRADE_LOCK_WHEN_LOADED 
       
   406          // A pessimistic synchronization grade 
       
   407     break;
       
   408     case: SyncProvider.GRADE_LOCK_WHEN_MODIFIED 
       
   409          // A pessimistic synchronization grade 
       
   410     break;
       
   411     case: SyncProvider.GRADE_NONE 
       
   412       // No synchronization with the originating data source provided
       
   413     break;
       
   414     }
       
   415 	  
       
   416     switch (sync.getDataSourcLock() {
       
   417       case: SyncProvider.DATASOURCE_DB_LOCK
       
   418        // A lock is placed on the entire datasource that is used by the
       
   419        // <code>RowSet</code> object 
       
   420        break;
       
   421 
       
   422       case: SyncProvider.DATASOURCE_NO_LOCK
       
   423        // No locks remain on the  originating data source.
       
   424       break;
       
   425 
       
   426       case: SyncProvider.DATASOURCE_ROW_LOCK
       
   427        // A lock is placed on the rows that are  touched by the original 
       
   428        // SQL statement used to populate
       
   429        // the RowSet object that is using the SyncProvider
       
   430        break;
       
   431 
       
   432       case: DATASOURCE_TABLE_LOCK
       
   433        // A lock is placed on  all tables that are touched by the original 
       
   434        // SQL statement used to populated
       
   435        // the RowSet object that is using the SyncProvider
       
   436        break;
       
   437 
       
   438 </PRE>
       
   439     It is also possible using the static utility method in the
       
   440 <code>SyncFactory</code> class to determine the list of <code>SyncProvider</code>
       
   441 implementations currently registered with the <code>SyncFactory</code>.
       
   442        
       
   443 <pre>
       
   444 	Enumeration e = SyncFactory.getRegisteredProviders();
       
   445 </pre>    
       
   446 
       
   447 </ul>
       
   448 
       
   449 <h3><a name="resolving">4.0 Resolving Synchronization Conflicts</h3>
       
   450 
       
   451 The interface <code>SyncResolver</code> provides a way for an application to
       
   452 decide manually what to do when a conflict occurs. When the <code>CachedRowSet</code>
       
   453 method <code>acceptChanges</code> finishes and has detected one or more conflicts,
       
   454 it throws a <code>SyncProviderException</code> object.  An application can
       
   455 catch the exception and
       
   456 have it retrieve a <code>SyncResolver</code> object by calling the method
       
   457 <code>SyncProviderException.getSyncResolver()</code>. 
       
   458 <P>
       
   459 A <code>SyncResolver</code> object, which is a special kind of 
       
   460 <code>CachedRowSet</code> object or
       
   461 a <code>JdbcRowSet</code> object that has implemented the <code>SyncResolver</code> 
       
   462 interface,  examines the conflicts row by row. It is a duplicate of the 
       
   463 <code>RowSet</code> object being synchronized except that it contains only the data
       
   464 from the data source this is causing a conflict. All of the other column values are
       
   465 set to <code>null</code>. To navigate from one conflict value to another, a
       
   466 <code>SyncResolver</code> object provides the methods <code>nextConflict</code> and
       
   467 <code>previousConflict</code>.
       
   468 <P>
       
   469 The <code>SyncResolver</code> interface also
       
   470 provides methods for doing the following:
       
   471 <UL>
       
   472  <LI>finding out whether the conflict involved an update, a delete, or an insert
       
   473  <LI>getting the value in the data source that caused the conflict
       
   474  <LI>setting the value that should be in the data source if it needs to be changed
       
   475      or setting the value that should be in the <code>RowSet</code> object if it needs
       
   476      to be changed
       
   477 </UL>
       
   478 <P>
       
   479 When the <code>CachedRowSet</code> method <code>acceptChanges</code> is called, it 
       
   480 delegates to the <code>RowSet</code> object's  <code>SyncProvider</code> object.
       
   481 How the writer provided by that <code>SyncProvider</code> object is implemented
       
   482 determines what level (grade) of checking for conflicts will be done.  After all 
       
   483 checking for conflicts is completed and one or more conflicts has been found, the method
       
   484 <code>acceptChanges</code> throws a <code>SyncProviderException</code> object. The
       
   485 application can catch the exception and use it to obtain a <code>SyncResolver</code> object.  
       
   486 <P>
       
   487 The application can then use <code>SyncResolver</code> methods to get information
       
   488 about each conflict and decide what to do.  If the application logic or the user
       
   489 decides that a value in the <code>RowSet</code> object should be the one to
       
   490 persist, the application or user can overwrite the data source value with it.  
       
   491 <P>
       
   492 The comment for the <code>SyncResolver</code> interface has more detail.
       
   493 
       
   494 <a name="relspec"><h3>5.0 Related Specifications</h3>
       
   495 <ul>
       
   496 <li><a href="http://java.sun.com/products/jndi">JNDI 1.3</a>
       
   497 <li><a href="{@docRoot}/../technotes/guides/logging/index.html">Java Logging
       
   498 APIs</a>
       
   499 </ul>
       
   500 <a name="reldocs"><h3>6.0 Related Documentation</h3>
       
   501 <ul>
       
   502 <li><a href="{@docRoot}/../technotes/tools/index.html#basic">System
       
   503 properties</a>
       
   504 <li>Resource Files
       
   505 <li><a href="http://java.sun.com/tutorial/jdbc">DataSource for JDBC
       
   506 Connections</a>
       
   507 </ul>
       
   508 
       
   509 </body>
       
   510 </html>