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