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 }