Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/apache/derby/iapi/jdbc/ResourceAdapter.java


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