KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > iapi > jdbc > ResourceAdapter


1 /*
2
3    Derby - Class org.apache.derby.iapi.jdbc.ResourceAdapter
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to you under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.iapi.jdbc;
23
24 import org.apache.derby.iapi.services.context.ContextService;
25 import org.apache.derby.iapi.store.access.xa.XAResourceManager;
26 import org.apache.derby.iapi.store.access.xa.XAXactId;
27 import org.apache.derby.iapi.error.StandardException;
28
29 /**
30     The resource adapter is the clearing house for managing connections,
31     transactions, and XAResources in a JDBC based resource manager living in
32     the distributed transaction processing environment.
33
34     <P> There is one instance of ResourceAdapter per Resource Manager (database).
35     The ResourceAdapter is responsible for keeping track of all run time global
36     transactions and their state. The resource adapter only knows of run time
37     global transactions, i.e., it does not know of in-doubt global transactions
38     re-created by recovery.
39
40     <P> The following is an overall design of the JTA implementation in cloudscape,
41     most of it has little to do with the ResourceAdapter interface itself.
42     <P><B>Design Overview </B>
43
44     <P>The overriding design principle is that existing code should be disturbed
45     as little as possible. This is so that DTP code will not add to the bloat
46     and drag of a normal, local, embbeded system. The second design principle
47     is that as much of the JDBC 2.0 extension functionality is to be
48     implemented in the Connectivity layer and not in the underlying storage
49     system as possible. Ideally, the additional storage interface will
50     implement no more than what is necessary to support the XAResource
51     interface.
52
53     <P>Language and replication code should not be touched, or have very
54     minimal API changes. The API changes are confined to passing XA calls down
55     to the store.
56
57     <P>Some change will be made to existing Connectivity code and new XA
58     modules will be added. This collection of code is hereby referred to as
59     the "blob of mysterious connectivity code", or the "resource adapter", or
60     "RA" for short. In the JTA doc, the resource adapter is considered to be
61     part of the JDBC driver. This RA means "some connectivity code", it
62     doesn't mean the object that implements the ResourceAdapter interface.
63
64     <P>The most important difference, in terms of implementation, between a
65     Connection that deals with a local transaction and a Connection that deals
66     with a global transaction is that in a global transaction, 2 or more
67     objects and threads can influence it - maybe concurrently. The normal JDBC
68     interaction goes thru the Connection, but transaction demarcation comes
69     from an XAResource object(s). The RA will channel all XAResource calls
70     that deal with a run time XA transaction (i.e., commit, end, forget,
71     prepare, start) thru the TransactionController that represents the real
72     transaction underneath. Furthermore, the RA will make sure that all calls
73     thru a Connection or thru any XAResource objects must pass thru some sort
74     of synchronized object before it can get to the underlying transaction
75     object. This is so that there is only one path to change the state of a
76     run time transaction and the transaction object and the context manager can
77     remain single thread access.
78
79     <P>In-doubt transaction (i.e., transactions re-created by recovery)
80     management and concurrency control is the responsibiliy of store. Moreover,
81     since the RA does not know the identities of the list of in-doubt
82     transactions, store must deal with (throw exception) when someone wants to
83     start a transaction with the same Xid as an existing in-doubt transaction.
84
85     <P>In terms of what this means to the app server that is calling us: if the
86     Connection and the XAResource that represents a global transaction is being
87     accessed by 2 different threads, they will access the database serially and
88     not concurrently. An in-doubt transaction gotten thru recovery has no
89     transaction object that is ever visible to the RA - because there is no
90     connection that was ever made to it. Therefore it is safe to influence the
91     state of an in-doubt transaction directly thru some store factory interface
92     - and have that go thru the transaction table underneath to find the actual
93     transaction object and context manager etc.
94
95     <P>One new functionality of a Connection is the ability to switch around
96     with different transactions. Before JTA, the lifetime of a transaction is
97     bounded by a connection, and a transaction cannot migrate from one
98     connection to another. In JTA, a global transaction can be detached from a
99     Connection. A transaction can move around and be attached to different
100     connections and its lifetime is not confine to the connection that started
101     it. From the Connection's point of view, before JTA, a (local) transaction
102     is always started and ended in the same connection. With JTA, it needs to
103     "take on" existing global transactions that was started by some other
104     connections.
105
106     <P>The RA will have the responsibility of
107     <OL>
108     <LI>setting up a Context with the appropriate transaction before calling
109     store to do work.</LI>
110     <LI>handling error on the context.</LI>
111     <LI>restoring a previous context if it was switched out due to an XAResouce
112     call to commit a transaction that is not what the XAResoruce is currently
113     attached to. </LI>
114     </OL>
115
116     <P>Because of all these switching around, a Connection may be in a
117     transaction-less state. This happens between an XAResource.end call that
118     detached the current global transaction from the Connection, and the next
119     XAResource.start call that attach the next global transaction with the
120     Connection.
121
122     <BR>An (inferior) implementation is for the Connection object to start a
123     local connection once it is detached from a global transaction. If the
124     user then uses the Connection immediately without a XAResource.start call,
125     then this Connection behaves just like it did before JTA, i.e., with a
126     local transaction. If, on the other hand, an XAResource.start call happens
127     next, then either the local transaction is "morphed" into a global
128     transaction, or, if the start call is to attach the connection to a
129     pre-existing global transaction, then the local transaction is thrown away
130     and the Connection will take on the pre-exising global transaction.
131
132     <BR>Another (superior) implementation is to make it possible for a
133     Connection to be transaction-less. When a Connection is first created by
134     XAConnection.getConnection, or when a XAResource.end call detached a global
135     transaction from the Connection, it is left in a transaction-less state.
136     If a XAResource.start call happens next, then the Connection either start a
137     new global transaction or it takes on an existing one. If a call is made
138     directly on the Connection before XAResource.start call happens, then the
139     Connection starts a new local transaction. This only affects Connections
140     that was gotten thru the XAConnection.getConnection(). Connections gotten
141     thru the DriverManager or a DataSource will have a local transaction
142     automatically started, as is the behavior today. When a Connection with a
143     local transaction commits, the transaction is still around but it is chain
144     to the next one - this is the current behavior. This behavior is very
145     desirable from a performance point of view, so it should be retained.
146     However, a local transaction cannot "morph" into a global transaction,
147     therefore when this Connection is attached to a global transaction, the
148     local transaction is thrown away and a global one started
149
150     <P>The RA will need to keep track of all global transactions. This is done
151     by (yet another) transaction table that lives in the RA. This transaction
152     table maps Xid to the ContextManager of the global transaction and whatever
153     else a connection needs to talk to the transaction - I assume the
154     Connection object currently have tendrils into various contexts and objects
155     and these are things that need to be detached and attached when a
156     Connection is hooked up with another transaction. The reason for yet
157     another transaction table instead of the one in store is because the one in
158     store keeps track of local and internal transactions and is really quite
159     overworked already.
160
161     <P><B>Detailed design</B>
162
163     <BR> First some ugly pictures. Some links are not shown to reduce
164     clutter. Externally visible object is in <B>bold</B>.
165   
166     <P><PRE>
167 *
168 * When user ask for an XAConnection via a XADataSource, the following objects
169 * exists
170 * <BR>
171 *
172 * |-------------|
173 * |======= produces=>| <B>XAResource</B> |
174 * || |-------------|
175 * || |
176 * || has A
177 * || |
178 * || |---------------------
179 * || V
180 * |--------------| produces |--------------|
181 * | <B>XADataSource</B> |=========>| <B>XAConnection</B>
182 * |--------------| |--------------|
183 * | |
184 * extends extends
185 * | |
186 * | |-----------------------| |----------------------|
187 * | | DB2jPooledConnection |==>| BrokeredConnection |
188 * | |-----------------------| |----------------------|
189 * | | ^ |
190 * | has A | has A
191 * | | | |
192 * |-----------------| | --------------------
193 * | EmbeddedDataSource | |
194 * |-----------------| |
195 * | |
196 * has A |
197 * | |
198 * V V
199 * |------------| |----------------------| |-----------------------|
200 * | JDBCDriver |=produces=>| DetachableConnection |==>| XATransactionResource |
201 * | LocalDriver| |----------------------| | |
202 * |------------| | | points to : |
203 * | |XATransactionController|
204 * | | ContextManager |
205 * | | LCC |
206 * | | .. etc .. |
207 * | |-----------------------|
208 * | |
209 * extends extends
210 * | |
211 * |-----------------| |-----------------------|
212 * | EmbedConnection |-- ?-->| TransactionResource |
213 * |-----------------| |-----------------------|
214 *
215 *
216 * <BR><BR>
217 * When user ask for a PooledConnection via a PooledDataSource, the following
218 * objects exists
219 * <BR>
220 * |-------------------------------|
221 * | <B>EmbeddedConnectionPoolDataSource</B> |
222 * |-------------------------------|
223 * | ||
224 * | ||
225 * extends produces
226 * | ||
227 * | \/
228 * | |-----------------------| |----------------------|
229 * | | <B>DB2jPooledConnection</B> |==>| <B>BrokeredConnection</B> |
230 * | |-----------------------| |----------------------|
231 * | | ^ |
232 * | has A | has A
233 * | | | |
234 * |-----------------| | --------------------
235 * | EmbeddedDataSource | |
236 * |-----------------| |
237 * | |
238 * has A |
239 * | |
240 * V V
241 * |------------| |----------------------| |-----------------------|
242 * | JDBCDriver |=produces=>| EmbedConnection |==>| TransactionResource |
243 * | LocalDriver| |----------------------| |-----------------------|
244 * |------------|
245 *
246 *
247 *
248 * <BR><BR>
249 * When user ask for a (normal) Connection via a DataSource, the following
250 * objects exists. The EmbeddedDataSource is just a wrapper for the JDBCDriver.
251 * <BR>
252 * |-----------------|
253 * | <B>EmbeddedDataSource</B> |
254 * |-----------------|
255 * |
256 * has A
257 * |
258 * V
259 * |------------| |-----------------| |-----------------------|
260 * | JDBCDriver |==produces=>| <B>EmbedConnection</B> |- ?->| TransactionResource |
261 * | LocalDriver| |-----------------| |-----------------------|
262 * |------------|
263
264     </PRE>
265
266     <P>XADataSource inherits DataSource methods from EmbeddedDataSource. It also
267     implements ResourceAdapter, whose main job is to keep track of run time
268     global transactions. A global transaction table maps XIDs to
269     XATransactionResource. XADataSource also has a XAResourceManager, which
270     implements XAResource functionality in the Store.
271     
272     <P>XAConnection is the one thing that unites a global connection and the
273     XAResource that delineates the global transaction. This is where the real
274     XAResource functionality is implemented. All XAResource calls to the
275     XAResource object as well as Connection call to the BrokeredConnection
276     channels thrus the XAConnection, which makes sure only one thread can be
277     accessing the DB2jPooledConnection at any given time.
278
279     <P>XAResource and BrokeredConnection[23]0 are the two objects we give back
280     to the TM and the user application respectively to control a distributed
281     transaction. According to the XA spec, the app server is supposed to make
282     sure that these objects are not used the same time by multiple threads, but
283     we don't trust the app server. Therefore, we channel everthing back to the
284     XAConnection.
285
286     <P>The MT consideration is actually more complicated than this,
287     because a XAResource is allowed to control any transaction, not just the
288     one its XAConnection is current attached to. So it is not sufficient to
289     just synchronized on XAConnection to guarentee single thread access to the
290     underlying transaction context. To control some arbitrary global
291     transaction, the TM can call XAResource to prepare any Xid. To do that,
292     the XAResource pass the request to the XAConnection, the XAConnection ask
293     the XADataSource to find the XATransactionResource, sets up the thread's
294     context, and call ask the XATransactionResource to prepare. The
295     XATransactionResource is synchronized to prevent some other thread from
296     attaching, commiting, and in any way calling on the the same transaction
297     context. If any error is thrown, it is handled with the context of the
298     transaction being prepared. After the error is handled, the old context
299     (the one where the XAResource is really attached to), is restored. While
300     this monkey business is going on, the thread that holds the connection the
301     XAConnection is supposed to be attached to is blocked out. It can resume
302     after its XAConnection restored its context. (Here is where I am not
303     really sure what happens since that thread obviously doesn't know about all
304     these hanky panky caused by the thread holding the XAResource commiting,
305     preparing and rolling back some other irrelavant transactions, so how would
306     its context be affected in any way?).
307
308     <P>DB2jPooledConnection implements PooledConnection, is hands out these
309     connection handles which allows some app server to do connection pooling.
310     This is a very thin layer. A connection handle implements a Connection by
311     passing thru all calls to the underlaying connection. In this case, it
312     passes Connection call thru the DB2jPooledConnection to the
313     DetachableConnection underneath.
314
315     <P>EmbeddedDataSource implements JNDI and is a replacement for Driver.
316
317     <P>The LocalDriver can now produce a DetachableConnection as well as a
318     EmbedConnection (which is the pre-JTA Connection that cannot detach and
319     attach to different transactions). The way the LocalDriver knows to create
320     a DetachableConnection versus a EmbedConnection is thru some extremely
321     hackish URL settings. This thing is very ugly and a more elegant way can
322     (and should) no doubt be found.
323
324     <P>DetachableConnection is a connection which can detach and attach to
325     different XATransactionResource, and can be totally unattached to any
326     transaction.
327
328     <P>XATransactionResource is a bundle of things that sets up a connection
329     with all the stuff it needs to actually talk to the database, do error
330     handling, etc. It is also the object that lives in the transaction table
331     managed by the ResourceAdapter (XADataSource). A XAResource (which may or
332     may not be attached to a transaction) can commit, prepare, or rollback any
333     global transaction that is not attached to an XAConnection. To do that,
334     the ResourceAdapter fishes out the XATransactionResource, set up the
335     context, and do the commit processing/error handling on the current
336     thread.
337
338     <P>Local Connection is the same old local Connection except one
339     difference. Pre-JTA, a localConnection uses itself (or a root Connection)
340     as the object to synchronized upon so that multiple threads getting hold of
341     the same Connection object cannot simultaneously issue calls to the
342     underlying transaction or context (since those things must be single thread
343     access). With JTA, the object of synchronization is the
344     TransactionResource itself. This part has not been well thought through
345     and is probably wrong.
346
347     <P>TransactionResource is a base class for XATransactionResource. For a
348     local transaction which cannot be detached from a connection, there is no
349     need to encapsulate a bundle of things to set up a connection, so a
350     TransactionResource (probably misnamed) has nothing and is used only for
351     synchronization purposes. This part has not been well thought throught and
352     is probably wrong.
353
354     <P>The non-XA PooledConnection is just a thin veneer over the normal
355     connection. I now have it over a Detachable connection just to simplify
356     the inheritence (XAConnection need to extend PooledConnection and XAConnect
357     needs to be detachable. However, PooledConnection itself need not be
358     detachable). It could be changed around to have LocalDriver producing
359     either EmbedConnection or XAConnection, and have the XAConnection
360     implements detachable. But the current way is simpler.
361
362  */

363 public interface ResourceAdapter {
364
365     /**
366         If a run time global transaction exists, the resource adapter will find
367         it and return a capsule of information so that a Connection can be
368         attached to the transaction.
369
370         @param xid the global transaction id
371         @return the transaction resource if the xid correspond to a run
372         time transaction, otherwise return null
373      */

374     //XATransactionResource findTransaction(XAXactId xid);
375

376     /**
377         Start a run time global transaction. Add this to the list of
378         transactions managed by this resource adapter.
379
380         @return true if transaction can be added, otherwise false (dupid).
381
382      */

383     //boolean addTransaction(XATransactionResource tr);
384

385     /**
386         Terminates a run time global transction. Remove this from the list of
387         transactions managed by this resource adapter.
388      */

389     //void removeTransaction(XATransactionResource tr);
390

391     /**
392         Let a xaResource get the XAResourceManager to commit or rollback an
393         in-doubt transaction.
394      */

395     XAResourceManager getXAResourceManager();
396
397     /**
398         Get the context service factory.
399      */

400     //ContextService getContextServiceFactory();
401

402     /**
403         Is the Resource Manager active
404      */

405     boolean isActive();
406
407     public Object JavaDoc findConnection(XAXactId xid);
408
409     public boolean addConnection(XAXactId xid, Object JavaDoc conn);
410
411     public Object JavaDoc removeConnection(XAXactId xid);
412
413 }
414
Popular Tags