Skip Headers
Oracle® Containers for J2EE Enterprise JavaBeans Developer's Guide
10g Release 3 (10.1.3)
B14428-02
  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
 

21 Configuring Transaction Services

This chapter describes:

For more information, see:

Configuring Transaction Timeouts

To improve application performance, you can configure a transaction timeout that determines how long OC4J will wait for a transaction to commit or rollback.

This section describes:

Configuring a Global Transaction Timeout

You can set a transaction timeout that applies globally to all transactions that OC4J manages for session and entity beans.

You can configure the global transaction timeout:

Using Application Server Control Console

Using the Application Server Control Console (see "Using Oracle Enterprise Manager 10g Application Server Control"), you can set the JTAResource MBean attribute transactionTimeout.

For more information, see "How to configure the OC4J Transaction Manager" in the Oracle Containers for J2EE Services Guide.

Using Deployment XML

In the <OC4J_HOME>\j2ee\home\config\transaction-manager.xml file you set the global transaction timeout with the transaction-timeout attribute of the <transaction-manager> element.

For example, if you wanted to set the global transaction timeout to 180 seconds, you would do as follows:

<transaction-manager ...  transaction-timeout="180"
  ...
</transaction-manager>

If you change this property using this method, you must restart OC4J to apply your changes. Alternatively, you can use Application Server Control Console to modify this parameter dynamically without restarting OC4J (see "Using Application Server Control Console").

Configuring a Transaction Timeout for a Session Bean

You can configure a transaction timeout for each session bean (see "Using Deployment XML"). The session bean transaction timeout overrides the global transaction timeout (see "Configuring a Global Transaction Timeout").

Using Deployment XML

In the orion-ejb-jar.xml file you set a session bean transaction timeout with the transaction-timeout attribute of the <session-deployment> element.

For example, if you wanted to set the global transaction timeout to 180 seconds, you would do as follows:

<session-deployment ...  transaction-timeout="180"
  ...
</session-deployment>

If you change this property using this method, you must restart OC4J to apply your changes.

Configuring a Transaction Timeout for a Message-Driven Bean

You can configure a transaction timeout on for each message-driven bean (see "Using Deployment XML").

Because the global transaction timeout (see "Configuring a Global Transaction Timeout") does not apply to message-driven beans, you must configure transaction timeout for each message-driven bean if you want to change the default transaction timeout for a message-driven bean.

The type of message service provider you use (see "What Message Providers Can I use with My MDB?") affects your transaction timeout options:

Using Deployment XML

You set the transaction timeout in the orion-ejb-jar.xml file. How you configure this value depends on the type of message-service provider you are using:

Non-J2CA Adapter Message Service Provider

If you are using a non-J2CA adapter message service provider like OracleAS JMS or Oracle JMS (OJMS), use the transaction-timeout attribute of the <message-driven-deployment> element.

For example, if you are using OracleAS JMS or Oracle JMS (OJMS), and you wanted to set the transaction timeout to 180 seconds, you would do as follows:

<message-driven-deployment ...  transaction-timeout="180"
  ...
</message-driven-deployment>

J2CA Adapter Message Service Provider

If you are using a J2CA adapter message service provider, use the <config-property> element to set the transactionTimeout configuration property.

For example, if you are using a J2CA adapter message service provider, and you wanted to set the transaction timeout to 180 seconds, you would do as follows:

<message-driven-deployment ... >
...
    <config-property>
        <config-property-name>transactionTimeout</config-property-name>
        <config-property-value>180</config-property-value>
    </config-property>
...
</message-driven-deployment>

In either case, if you change this property using this method, you must restart OC4J to apply your changes.

Transaction Best Practices

This section describes the preferred approach to using transactions in an EJB application, including:

Using Container Managed Transactions with Datasource Connections

If you are using container-managed transactions, and you use a data source connection, bear in mind that the connection is not released until the transaction commits. This is particularly important if you are using the data source connection in a loop: in this case, you should acquire and release the connection outside of the loop to avoid inadvertently exhausting your connection pool.

Consider a session bean that you configure for container-managed transactions. This session bean has method runQueryConnectionEveryTime as Example 21-1 shows. When this method is called, a container-managed transaction is opened. In each iteration of the for loop, a connection is acquired and closed. However, the closed connection is not released until the method returns and the container-managed transaction commits. Depending on the number of iterations, this design can exhaust your connection pool.

To avoid this problem, you should acquire and close the connection outside of the loop as Example 21-2 shows. By doing so, you guarantee that only one connection will be held until the container-managed transaction commits.

Example 21-1 Incorrect: count Number of Connections Held Until Commit

public static long runQueryConnectionEveryTime (int count)
{
    InitialContext ic = new InitialContext();
    DataSource ds = (DataSource) ic.lookup("jdbc/OracleDS");

    for (int i = 0; i < count; i++)
    {
        Connection con = ds.getConnection();     //connection created inside loop

        PreparedStatement ps = con.prepareStatement(
            "select AAA_ID, AAA_A FROM AAA_TABLE where AAA_ID = ? "
        );

        OracleStatement os = (OracleStatement)ps;
        os.defineColumnType(1, Types.BIGINT);
        ps.setLong(1, i);
        ResultSet rs = ps.executeQuery();
        rs.close();
        ps.close();

        con.close(); //connection closed inside loop
    }
}

Example 21-2 Correct: Only One Connection Held Until Commit

public static long runQueryConnectionEveryTime (int count)
{
    InitialContext ic = new InitialContext();
    DataSource ds = (DataSource) ic.lookup("jdbc/OracleDS");

    Connection con = ds.getConnection();    //connection created outside loop


    for (int i = 0; i < count; i++)
    {
        PreparedStatement ps = con.prepareStatement(
            "select AAA_ID, AAA_A FROM AAA_TABLE where AAA_ID = ? "
        );

        OracleStatement os = (OracleStatement)ps;
        os.defineColumnType(1, Types.BIGINT);
        ps.setLong(1, i);
        ResultSet rs = ps.executeQuery();
        rs.close();
        ps.close();
    }

    con.close(); //connection closed outside loop
} 

Using a Rollback Strategy

An enterprise bean with container-managed transaction demarcation can use the setRollbackOnly method of its javax.ejb.EJBContext object to mark the transaction such that the transaction can never commit.

Typically, you would do this to protect data integrity before throwing an application exception when the application exception does not automatically cause the container to rollback the transaction.

For example, an AccountTransfer bean which debits one account and credits another account could mark a transaction for rollback if it successfully performs the debit, but fails during the credit operation.

For more information, see: