J. Duke | 319a3b9 | 2007-12-01 00:00:00 +0000 | [diff] [blame^] | 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> |