Skip Headers
Oracle® Application Server TopLink Application Developer's Guide
10g Release 2 (10.1.2)
Part No. B15901-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

J2EE Integration

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:

External Connection Pooling

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.

When to Use External Connection Pools

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.

Configuring an External Connection Pool in sessions.xml

To configure the use of an external connection pool in the sessions.xml file:

  1. Configure the DataSource on the server.

  2. 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>
    

Configuring an External Connection Pool in Java

To configure the use of an external connection pool in Java:

  1. Configure the DataSource on the server.

  2. 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);
    

External Transaction Controllers

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

Configuring an External Transaction Controller in sessions.xml

To configure the use of an external transaction controller in the sessions.xml file:

  1. Configure a JTA-enabled DataSource on the server.

    For more information, see the J2EE container documentation.

  2. 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>
    
    
  3. 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>
    

Configuring an External Transaction Controller in Java

To configure the use of an external transaction controller in Java:

  1. Configure a JTA-enabled DataSource on the server.

    For more information, see the J2EE container documentation.

  2. 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);
    
    
  3. Configure the session to use a particular instance of ExternalTransactionController:

    serverSession.setExternalTransactionController(
        new Oracle9iJTSExternalTransactionController()
    );
    

Acquiring a Unit of Work in a JTA Environment

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 the getActiveUnitOfWork 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
    }

Using a Unit of Work When an External Transaction Exists

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

Description of uow_ex.gif follows
Description of the illustration uow_ex.gif

Using a Unit of Work When No 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

Description of uow_noex.gif follows
Description of the illustration uow_noex.gif