001: /*
002:
003: Derby - Class org.apache.derby.iapi.jdbc.ResourceAdapter
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.iapi.jdbc;
023:
024: import org.apache.derby.iapi.services.context.ContextService;
025: import org.apache.derby.iapi.store.access.xa.XAResourceManager;
026: import org.apache.derby.iapi.store.access.xa.XAXactId;
027: import org.apache.derby.iapi.error.StandardException;
028:
029: /**
030: The resource adapter is the clearing house for managing connections,
031: transactions, and XAResources in a JDBC based resource manager living in
032: the distributed transaction processing environment.
033:
034: <P> There is one instance of ResourceAdapter per Resource Manager (database).
035: The ResourceAdapter is responsible for keeping track of all run time global
036: transactions and their state. The resource adapter only knows of run time
037: global transactions, i.e., it does not know of in-doubt global transactions
038: re-created by recovery.
039:
040: <P> The following is an overall design of the JTA implementation in cloudscape,
041: most of it has little to do with the ResourceAdapter interface itself.
042: <P><B>Design Overview </B>
043:
044: <P>The overriding design principle is that existing code should be disturbed
045: as little as possible. This is so that DTP code will not add to the bloat
046: and drag of a normal, local, embbeded system. The second design principle
047: is that as much of the JDBC 2.0 extension functionality is to be
048: implemented in the Connectivity layer and not in the underlying storage
049: system as possible. Ideally, the additional storage interface will
050: implement no more than what is necessary to support the XAResource
051: interface.
052:
053: <P>Language and replication code should not be touched, or have very
054: minimal API changes. The API changes are confined to passing XA calls down
055: to the store.
056:
057: <P>Some change will be made to existing Connectivity code and new XA
058: modules will be added. This collection of code is hereby referred to as
059: the "blob of mysterious connectivity code", or the "resource adapter", or
060: "RA" for short. In the JTA doc, the resource adapter is considered to be
061: part of the JDBC driver. This RA means "some connectivity code", it
062: doesn't mean the object that implements the ResourceAdapter interface.
063:
064: <P>The most important difference, in terms of implementation, between a
065: Connection that deals with a local transaction and a Connection that deals
066: with a global transaction is that in a global transaction, 2 or more
067: objects and threads can influence it - maybe concurrently. The normal JDBC
068: interaction goes thru the Connection, but transaction demarcation comes
069: from an XAResource object(s). The RA will channel all XAResource calls
070: that deal with a run time XA transaction (i.e., commit, end, forget,
071: prepare, start) thru the TransactionController that represents the real
072: transaction underneath. Furthermore, the RA will make sure that all calls
073: thru a Connection or thru any XAResource objects must pass thru some sort
074: of synchronized object before it can get to the underlying transaction
075: object. This is so that there is only one path to change the state of a
076: run time transaction and the transaction object and the context manager can
077: remain single thread access.
078:
079: <P>In-doubt transaction (i.e., transactions re-created by recovery)
080: management and concurrency control is the responsibiliy of store. Moreover,
081: since the RA does not know the identities of the list of in-doubt
082: transactions, store must deal with (throw exception) when someone wants to
083: start a transaction with the same Xid as an existing in-doubt transaction.
084:
085: <P>In terms of what this means to the app server that is calling us: if the
086: Connection and the XAResource that represents a global transaction is being
087: accessed by 2 different threads, they will access the database serially and
088: not concurrently. An in-doubt transaction gotten thru recovery has no
089: transaction object that is ever visible to the RA - because there is no
090: connection that was ever made to it. Therefore it is safe to influence the
091: state of an in-doubt transaction directly thru some store factory interface
092: - and have that go thru the transaction table underneath to find the actual
093: transaction object and context manager etc.
094:
095: <P>One new functionality of a Connection is the ability to switch around
096: with different transactions. Before JTA, the lifetime of a transaction is
097: bounded by a connection, and a transaction cannot migrate from one
098: connection to another. In JTA, a global transaction can be detached from a
099: 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: 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: Terminates a run time global transction. Remove this from the list of
385: transactions managed by this resource adapter.
386: */
387: //void removeTransaction(XATransactionResource tr);
388: /**
389: Let a xaResource get the XAResourceManager to commit or rollback an
390: in-doubt transaction.
391: */
392: XAResourceManager getXAResourceManager();
393:
394: /**
395: Get the context service factory.
396: */
397: //ContextService getContextServiceFactory();
398: /**
399: Is the Resource Manager active
400: */
401: boolean isActive();
402:
403: public Object findConnection(XAXactId xid);
404:
405: public boolean addConnection(XAXactId xid, Object conn);
406:
407: public Object removeConnection(XAXactId xid);
408:
409: }
|