Oracle® Application Server TopLink Application Developer's Guide
10g Release 2 (10.1.2) Part No. B15901-01 |
|
Previous |
Next |
OracleAS TopLink J2EE integration provides support for external datasources and external transaction controllers. Together, these features provide support for JTA. This enables you to incorporate external container support into your application, and to use JTA transactions.
This section describes:
For most non-J2EE applications, OracleAS TopLink provides an internal connection or pool of connections. However, most J2EE applications use external connection pooling offered by the J2EE Container JTA DataSource
. For J2EE applications, OracleAS TopLink integrates with the J2EE Container connection pooling.
External connection pools enable your OracleAS TopLink application to:
Integrate into a J2EE-enabled system.
Integrate with JTA transactions (JTA transactions require a JTA-enabled DataSource
).
Leverage a shared connection pool in which multiple applications use the same DataSource
.
Use a DataSource
configured and managed directly on the server.
Leverage a datasource that is accessible only through the DataSource
interface.
Configure OracleAS TopLink to use the built-in JTA integration support to take advantage of these benefits. Without JTA, external connection pools generally offer benefits only if transactions in an OracleAS TopLink application are independent of each other and any other transactions in the system. In that case, the complexities of an OracleAS TopLink connection or connection pool are unnecessary.
To configure the use of an external connection pool in the sessions.xml
file:
Configure the DataSource
on the server.
Add the following elements to the login
tag in the sessions.xml
file to specify a DataSource
and the use of an external connection pool:
<data-source>jdbc/MyApplicationDS</data-source> <uses-external-connection-pool>true</uses-external-connection-pool>
To configure the use of an external connection pool in Java:
Configure the DataSource
on the server.
Configure the Login
to specify a DataSource
and the use of an external connection pool:
login.setConnector( new JNDIConnector(new InitialContext(), "jdbc/MyApplicationDS") ); login.setUsesExternalConnectionPooling(true);
A transaction controller is an OracleAS TopLink class that synchronizes the session cache with the data on the database. The transaction controller manages messages and callbacks from the J2EE transaction. On commit, the transaction controller executes the Unit of Work SQL on the database, and merges changed objects into the OracleAS TopLink session cache. Because JTA transaction controllers require a JTA-enabled DataSource
, configure an external transaction controller and enable OracleAS TopLink external connection pool support.
OracleAS TopLink provides transaction controllers for container-specific support, as well as generic controllers that can be used for other specification-conforming servers.
Table 7-3 lists the custom external transaction controllers OracleAS TopLink provides.
Table 7-3 OracleAS TopLink Custom External Transaction Controllers
Application Server or J2EE Container | OracleAS TopLink External Transaction Controller |
---|---|
Oracle Application Server Containers for J2EE
|
oracle.toplink.jts.oracle9i.Oracle9iJTSExternalTransactionController |
IBM WebSphere 3.5 | oracle.toplink.jts.was.WebSphereJTSExternalTransactionController |
IBM WebSphere 4.0 | oracle.toplink.jts.was.JTSExternalTransactionController_4_0 |
IBM WebSphere 5.0 | oracle.toplink.jts.was.JTSExternalTransactionController_5_0 |
BEA WebLogic | oracle.toplink.jts.wls.WebLogicJTSExternalTransactionController |
Other JTA Container | oracle.toplink.jts.JTSExternalTransactionController |
To configure the use of an external transaction controller in the sessions.xml
file:
Configure a JTA-enabled DataSource
on the server.
For more information, see the J2EE container documentation.
Add the following elements to the login
tag in the sessions.xml
file to specify a DataSource
, the use of an external transaction controller, and the use of an external connection pool:
<data-source>jdbc/MyApplicationDS</data-source> <uses-external-transaction-controller> true </uses-external-transaction-controller> <uses-external-connection-pool>true</uses-external-connection-pool>
Specify an external transaction controller class in the sessions.xml
file.
For example:
<external-transaction-controller-class> oracle.toplink.jts.oracle9i.Oracle9iJTSExternalTransactionController </external-transaction-controller-class>
To configure the use of an external transaction controller in Java:
Configure a JTA-enabled DataSource
on the server.
For more information, see the J2EE container documentation.
Configure the Login
to specify a DataSource
, the use of an external transaction controller, and the use of an external connection pool:
login.setConnector( new JNDIConnector(new InitialContext(), "jdbc/MyApplicationDS") ); login.setUsesExternalTransactionController(true); login.setUsesExternalConnectionPooling(true);
Configure the session to use a particular instance of ExternalTransactionController
:
serverSession.setExternalTransactionController( new Oracle9iJTSExternalTransactionController() );
You use a Unit of Work to write to a database, even in a JTA environment. To ensure that only one Unit of Work is associated with a given transaction, use the getActiveUnitOfWork
method to acquire a Unit of Work, as shown in Example 7-29.
Note: Although there are other ways to write to a database through a JTA external controller, using thegetActiveUnitOfWork method is the safest approach to database updates under JTA.
|
The getActiveUnitOfWork
method searches for an existing external transaction:
If there is an active external transaction and a Unit of Work is already associated with it, then return this Unit of Work.
If there is an active external transaction with no associated Unit of Work, then acquire a new Unit of Work, associate it with the transaction, and return it.
If there is no active external transaction in progress, then return null.
If a non-null Unit of Work is returned, use it exactly as you would in a non-JTA environment. The only exception is that you do not call the commit
method (see "Using a Unit of Work When an External Transaction Exists").
If a null Unit of Work is returned, start an external transaction either explicitly through the UserTransaction
interface, or by acquiring a new Unit of Work using the acquireUnitOfWork
method on the client session (see "Using a Unit of Work When No External Transaction Exists").
Example 7-29 Using a Unit of Work in a JTA Transaction
boolean shouldCommit = false; // Read in any pet. Pet pet = (Pet)clientSession.readObject(Pet.class); UnitOfWork uow = clientSession.getActiveUnitOfWork(); if (uow == null) { uow = clientSession.acquireUnitOfWork(); // Start external transaction shouldCommit = true; } Pet petClone = (Pet) uow.registerObject(pet); petClone.setName("Furry"); if (shouldCommit) { uow.commit(); // Ask external transaction controller to commit }
When getActiveUnitOfWork
returns a non-null Unit of Work, you are associated with an existing external transaction. Use the Unit of Work as usual.
Because the external transaction was not started by the Unit of Work, issuing a commit
on it does not cause the JTA transaction to be committed. The Unit of Work defers to the application or container that began the transaction. When the external transaction does get committed by the container, OracleAS TopLink receives sychronization callbacks at key points during the commit.
The Unit of Work sends the required SQL to the database when it receives the beforeCompletion
call back.
The Unit of Work uses the boolean argument received from the afterCompletion
call back to determine if the commit was successful (true) or not (false).
If the commit was successful, the Unit of Work merges changes to the session cache. If the commit was unsuccessful, the Unit of Work discards the changes.
Figure 7-4 Unit of Work When an External Transaction Exists
When getActiveUnitOfWork
returns a null Unit of Work, there is no existing external transaction. You must start a new external transaction.
Do this either by starting an external transaction explicitly using the UserTransaction
interface, or by acquiring a new Unit of Work using the acquireUnitOfWork
method on the server session.
Use the Unit of Work as usual.
Once the modifications to registered objects are complete, you must commit the transaction either explicitly through the UserTransaction
interface or by calling the Unit of Work commit
method.
The transaction synchronization callbacks are then invoked on OracleAS TopLink and the database updates and cache merge occurs based upon those callbacks.
Figure 7-5 Unit of Work When No External Transaction Exists