2
|
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 |
<!--
|
5506
|
11 |
Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
|
2
|
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
|
5506
|
16 |
published by the Free Software Foundation. Oracle designates this
|
2
|
17 |
particular file as subject to the "Classpath" exception as provided
|
5506
|
18 |
by Oracle in the LICENSE file that accompanied this code.
|
2
|
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>
|