JDBC 2.0 core API assumes a 2-tier data access model, where applications access physical connections provided by the database driver directly. JDBC 2.0 Optional (formerly known as Standard Extension) API adds provisions for a 3-tier data access model, where applications access logical connections via middle-tier server. This allows the middle-tier server to optionally implement more sophisticated features like connection pooling and distributed transactions.
WLS JDBC 2.0 resource adapter encapsulates the middle-tier logic between the application and the driver to implement connection pooling, and also the middle-tier logic between the transaction manager and the driver to implement distributed transactions.
In the WLS environment, the WLS JDBC 2.0 resource adapter serves the following purposes:
1. Acts as a bridge between application and JDBC 2.0 resource:
It provides implementation of javax.sql.DataSource
interface on
top of JDBC 2.0 XA driver's javax.sql.XADataSource
interface.
2. Manages usage of JDBC 2.0 resources:
It implements connection pooling for JDBC 2.0 XA driver's XA connections, and manages the usage of XA connections efficiently.
3. Acts as a bridge between WLS transaction manager and JDBC 2.0 resource:
XAResource.start
operation. It is also
needed by the transaction object's propagation logic to be included in the
participant resource list in the transaction propagation context.
4. Acts as a bridge between WLS OA&M subsystem and JDBC 2.0 resource:
It communicates bidirectionally with the WLS OA&M subsystem about resource properties and any changes. It initializes the JDBC 2.0 XA driver's data source and makes it available to be used by doing the following:
java.sql
and javax.sql
interfaces.
Similarly, being a bridge between the transaction manager and JDBC 2.0 XA
drivers, the JDBC 2.0 resource adapter provides logical XA resources on top of
the physical XA resource provided by the drivers. This logical XA resource
object is only used internally by the WLS transaction manager, and implements
the standard javax.transaction.xa.XAResource
interface and a WLS
extension tbd
interface.
The resource adapter's logical XA resource differs from the physical ones provided by the drivers as follow:
XAResource.isSameRM()
method to determine whether two XA resource objects are from the same data
source. Having logical JDBC and XA resource objects allows the JDBC 2.0 resource adapter to intercept various JDBC and XA resource calls and performs various optimizations in addition to providing basic connection pooling and distributed transactions functionality. See Database connection management and Optimizations sections below.
1. For JDBC operations (called by the application onto the resource adapter's logical connections) that do not require a XA connection, the resource adapter just returns the required logical JDBC objects (e.g. statements) without obtaining a XA connection from the pool.
2. For JDBC operations (called by the application onto the resource adapter's logical JDBC objects) that require XA connection but do not require a transaction context, the resource adapter obtains a XA connection on demand and return the XA connection back to pool after usage.
3. For JDBC operations (called by the application onto the resource adapter's logical JDBC objects) that require a transaction context, the resource adapter obtains a XA connection on demand.
If there is a (global) transaction context, the resource adapter also
enlists its logical XA resource to the transaction manager. Multiple requests
for XA connection in the same transaction will use the same XA connection.
The XA connection is returned back to the pool when the transaction manager
calls XAResource.end(TMSUCCESS or TMFAIL)
on the resource adapter's
logical XA resource object. This happens either when making outcall or when
method returns with no result sets in the transaction, or when the transaction
is committed or rolled back.
If there is no transaction context, no resource enlistment is done.
For some RM, e.g. Oracle, the RM will start a local transaction implicitly.
In this case, the XA connection is returned back to the pool when the
application completes the local transaction via calling
Connection.commit()
or Connection.rollback()
on the
resource adapter's logical connection object. XA resource operations will not
be called for local transactions.
4. For XA resource operations other than start/end that is being called by the transaction manager onto the resource adapter's logical XA resource object, the resource adapter obtains a XA connection and returns the connection back to pool every time.
Transaction.enlistResource
and
Transaction.delistResource
respectively. The transaction object
in turns performs the transaction association and disassociation with and from
the XA resources by calling XAResource.start
and
XAResource.end
respectively. This is done so that data access
performed with the associating XA connections will be done in the same
transaction context.
The resource adapter and the transaction manager handles resource enlistment and delistment as follow:
1. The resource adapter enlists its logical XA resource object with the
transaction manager blindly before any JDBC operations (called by the
application onto the logical JDBC objects) that need a transaction context.
The transaction manager will ignore duplicate enlists and will call
XAResource.start
on the resource adapter's logical XA resource
object with the appropriate flag if needed. The resource adapter's logical
XA resource will delegate the XAResource.start
call to the
driver's XAResource.start
directly.
2. The resource adapter does not perform any
Transaction.delistResource
. It always rely on the transaction
manager to ask it for the proper delist flag when it is ready to call
XAResource.end
on the resource adapter's logical XA resource object
(when making outcalls or returning from method). The resource adapter's logical
XA resource will delegate the XAResource.end
call to the driver's
XAResource.end
directly. In addition, the logical XA resource
object will return the XA connection back to the pool if the delist flag is
TMSUCCESS
or if there is no result sets opened in the transaction.
recover
method in this case.
However, resources can also crash or become unreachable due to network partition etc. For these cases, when the resource comes back up or becomes reachable again, the only recoverable action that needs to be done is to refresh the connections of the resources. The resource adapter will attempt to reconnect implicitly when XAER_RMERR results from XA operations. An administrative command should also be available to force the refresh of connections. After the connection refresh, the normal 2PC protocol of the transaction manager will take over to drive the pending transactions to completion as normal.
1. Getting connection before transaction begin.
2. Completing transaction before connection is closed.
3. Getting and closing connections in a nested manner.
4. Leave result sets open across outcall.
5. Leave result sets open across method invocations.
6. Usage of both local and global transactions with same connection.
7. Setting auto commit to true when connection is used in local transaction. However, auto commit will be reset to default (false) when local transaction is completed.
8. Interleave different global transactions with the same connection.
1. Obtaining XA connections lazily on demand. (for both local and global transaction)
2. Different logical connections share the same XA connection if they are in the same transaction. (for global transaction)
3. Returning XA connections back to pool as early as possible:
4. Delay XAResource.end
until making outcalls or method end.
This avoid unnecessary XAResource.start
later in the same method
call when additional data access work is done in the same transaction. (for
global transaction)
javax.sql
javax.transaction
javax.transaction.xa