BEA Logo BEA WebLogic Enterprise Release 5.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

 

   WebLogic Enterprise Doc Home   |   Transaction Topics   |   Previous Topic   |   Next Topic   |   Contents   |   Index

Transactions and the WebLogic Enterprise JDBC/XA Driver

 

This topic includes the following sections:

This topic describes how to integrate transactions with CORBA Java, EJB, and RMI applications that use the WebLogic Enterprise JDBC/XA driver and run under BEA WebLogic Enterprise. Before you begin, you should read Introducing Transactions.

 


Before You Begin

This chapter describes handling transactions in CORBA Java, EJB, and RMI applications that use the WebLogic Enterprise JDBC/XA driver to connect to resources.

For EJB applications, the information in this document supplements the Enterprise JavaBeans Specification 1.1 published by Sun Microsystems, Inc. For general information about implementing Enterprise JavaBeans in WebLogic Enterprise applications, see "Developing WebLogic Enterprise EJB Applications" in Getting Started.

 


About Transactions and the WebLogic Enterprise JDBX/XA Driver

This topic includes the following sections:

Support for Transactions Using the WebLogic Enterprise JDBC/XA Driver

WebLogic Enterprise provides a multithreaded JDBC/XA driver for Oracle Corporation's Oracle8i database management system. The WebLogic Enterprise JDBC/XA driver fully supports XA, the bidirectional system-level interface between a transaction manager and a resource manager of the X/Open Distributed Transaction Processing (DTP) model. This driver is available to CORBA Java, EJB, and RMI applications and runs in the WebLogic Enterprise environment only.

Pooled Connections

Java applications use the WebLogic Enterprise JDBC/XA driver to establish concurrent connections to multiple Oracle8i databases via their associated resource managers. For distributed transactions, applications must obtain database connections from the JDBC connection pool. (However, this is not a requirement for other jdbcKona drivers in local transaction mode or for third-party drivers.) Thereafter, applications perform database operations using standard JDBC API calls.

A JDBC connection is governed by the pooled connection lifecycle in the JDBC connection pool. As such, the application server might implicitly close JDBC/XA connections to enforce certain personality-specific transactional resource restrictions, as described in JDBC Accessibility in Java Methods. For more information about using WebLogic Enterprise JDBC connection pools with WebLogic Enterprise JDBC/XA driver, see "Using JDBC Connection Pooling" in Using the JDBC Drivers.

Characteristics of JavaServerXA

The JavaServerXA server hosts the WebLogic Enterprise JDBC/XA driver. The JavaServerXA has the following characteristics:

Supported JDBC Standards

WebLogic Enterprise fully supports the JDBC 1.22 API (core functionality), the JDBC 2.0 Core API, and the distributed transactions (the javax.sql.DataSource API), connection pooling, and JNDI capabilities in the JDBC 2.0 Optional Package API. See Using the JDBC Drivers for a complete list of WebLogic Enterprise-supported JDBC 2.0 features.

Local Versus Distributed (Global) Transactions

WebLogic Enterprise applications using the WebLogic Enterprise JDBC/XA driver can perform local transactions as well as distributed (also called global) transactions. A local transaction involves updates to a single resource manager (such as a database), while a distributed transaction involves updates across multiple resource managers.

The WebLogic Enterprise JDBC/XA driver never starts a local transaction on behalf of an application. However, if the application performs database operations without first explicitly starting a distributed transaction, then these database operations occur within an "unspecified transaction context" and WebLogic Enterprise delegates the responsibility of handling this situation to the database.

In Oracle8i, for example, the database might start a local transaction to perform such database operations.

Failure to commit a local transaction may result in XAER_OUTSIDE error (indicating that the resource manager is performing work outside a distributed transaction) on subsequent distributed transaction operations, which includes beginning a distributed transaction. It is the responsibility of the application to be aware of the transaction context at any point and to complete distributed or local transactions appropriately.

Differences Between Local and Distributed Transactions

Table 7-1 lists differences between local and distributed transactions.

Table 7-1 Differences Between Local and Distributed Transactions

Category

Local Transactions

Distributed Transactions

Resource Managers/Databases

Single database / resource manager

Can span across multiple resource managers

Transaction Demarcation API

Can use the following API:

java.sql.Connection

Can use either of following APIs:

CORBA API
org.omg.CosTransaction
TransactionCurrent
API

EJB API:

javax.transaction
UserTransaction
API

Autocommit

Can be enabled or disabled

Must be disabled

Configuring the ENABLEXA Parameter in the UBBCONFIG

To use the WebLogic Enterprise JDBC/XA driver, you must specify the ENABLEXA parameter (ENABLEXA=Y) in the JDBCCONNPOOLS section of the UBBCONFIG, as shown in Listing 7-1. In this example, distributed transactions are enabled for the bank_pool connection pool.

Note: This setting applies only to the WebLogic Enterprise JDBC/XA driver.

Listing 7-1 Specifying JDBCCONNPOOLS Information in UBBCONFIG


JDBCCONNPOOLS
bank_pool
SRVGRP = BANK_GROUP1
SRVID = 2
DRIVER = "weblogic.jdbc20.oci815.Driver"
URL = "jdbc:weblogic:oracle:Beq-local"
PROPS = "user=scott;password=tiger;server=Beq-Local"
ENABLEXA = Y
INITCAPACITY = 2
MAXCAPACITY = 10
CAPACITYINCR = 1
CREATEONSTARTUP = Y


For more information about configuring JDBC connection pools, see "Using JDBC Connection Pooling" in Using the JDBC Drivers.

Demarcating Transaction Boundaries for Local and Distributed Transaction Contexts

Applications must carefully and explicitly demarcate transaction boundaries between distributed and local transaction contexts. For example, when an application uses the WebLogic Enterprise JDBC/XA driver to connect to a database:

Transaction Contexts in WebLogic Enterprise JDBC/XA Connections

For WebLogic Enterprise JDBC/XA connections, database operations will always be performed in the current transaction context. For example, an application might obtain a JDBC/XA connection in a NULL transaction context, begin a distributed transaction, and then perform database operations using that connection. These database operations will be performed in the context of the current distributed transaction.

Applications use WebLogic Enterprise JDBC/XA connection API in the same way as other jdbcKona connections except that, while within a distributed transaction context:

Listing 7-3 shows, in a sample CORBA Java application, how to determine the current transaction context and commit a local or global transaction accordingly.

Listing 7-3 Determining Whether the Application Is in a Distributed Transaction


// Assumes that org.omg.CosTransactions.Current (tc) and
// java.sql.Connection (con) were initialized before
// database operations were attempted
if (tc.get_status() != org.omg.CosTransactions.Status.StatusNoTransaction)
{
// Application is currently in a distributed transaction
tc.commit(true);
}
else
{
// Application is currently in a local transaction
con.commit();
}


Similarly, for bean-managed transactions in an EJB application, the application can determine whether the application is currently in a distributed transaction by calling the UserTransaction.getStatus() method and testing for a returned STATUS_NO_TRANSACTION.

 


JDBC Accessibility in Java Methods

This topic includes the following sections:

JDBC/XA Accessibility in CORBA Methods

Table 7-2 lists which methods in CORBA methods can access JDBC/XA connections.

Table 7-2 JDBC/XA Connection Accessibility for CORBA Objects

Server Method

Accessibility

Constructor

Not supported

initialize

Supported, after open_xa_rm

activate_obj

Supported

deactivate_obj

Supported

Business method

Supported

release

Supported, before close_xa_rm

After completing the initialize method, WebLogic Enterprise automatically closes any open connections and writes a warning message to the ULOG.

For transaction-bound and process-bound objects, the CORBA framework allows open connections to be retained at method end, and the transaction context of the retained connections will be as described in Transaction Contexts in WebLogic Enterprise JDBC/XA Connections upon subsequent method invocations. However, for method-bound objects, applications must explicitly close open connections before method end. If not, WebLogic Enterprise automatically closes any open connections and writes a warning message to the ULOG.

JDBC/XA Accessibility in EJB Methods

For EJB methods, accessibility to JDBC/XA connections varies depending on the EJB type. For details about retaining JDBC/XA connections across method invocations (for stateful session beans only), including examples, see Section 11.3.3 in the Enterprise JavaBeans Specification 1.1, published by Sun Microsystems, Inc.

Note: For all bean types, after completing the ejbCreate method, WebLogic Enterprise automatically closes any open connections and writes a warning message to the ULOG.

Stateful Session Beans

Table 7-3 lists which stateful session bean methods can access JDBC/XA connections.

Table 7-3 JDBC/XA Connection Accessibility for Stateful Session Beans

Bean Method

Container-managed Transaction

Bean-managed Transaction

Constructor

Not supported

Not supported

setSessionContext

Not supported

Not supported

ejbCreate

ejbRemove

ejbActivate

ejbPassivate

Supported, but in unspecified transaction context (as defined in the Enterprise JavaBeans 1.1 specification)

Supported, but in unspecified transaction context (as defined in the Enterprise JavaBeans 1.1 specification), unless the bean explicitly begins a transaction using UserTransaction

Business method

Supported

Supported

afterBegin

Supported

N/A

beforeCompletion

Supported

N/A

afterCompletion

Supported

N/A

For stateful session beans, the Bean Provider must close all JDBC connections in ejbPassivate and assign the instance's fields storing the connections to null. However, after completing the ejbPassivate method, WebLogic Enterprise automatically closes any open connections and writes a warning message to the ULOG.

Stateless Session Beans

Table 7-4 lists which stateless session bean methods can access JDBC/XA connections.

Table 7-4 JDBC/XA Connection Accessibility for Stateless Session Beans

Bean Method

Container-managed Transaction

Bean-managed Transaction

Constructor

Not supported

Not supported

setSessionContext

Not supported

Not supported

ejbCreate

Not supported

Not supported

ejbRemove

Not supported

Not supported

Business method

Supported

Supported

Note: For stateless session beans, after completing a business method, WebLogic Enterprise automatically closes any open connections and writes a warning message to the ULOG.

Entity Beans

Table 7-5 lists which entity bean methods can access JDBC/XA connections.

Table 7-5 JDBC/XA Connection Accessibility for Entity Beans

Bean Method

Accessibility

Constructor

Not supported

setEntityContext

Not supported

unsetEntityContext

Not supported

ejbCreate

Supported

ejbPostCreate

Supported

ejbRemove

Supported

ejbFind

Supported

ejbActivate

Not supported

ejbPassivate

Not supported

ejbLoad

Supported

ejbStore

Supported

business method

Supported

 


Using the JDBC/XA Driver

Before applications can use the WebLogic Enterprise JDBC/XA driver, the JDBC/XA driver must be integrated into your development environment by completing the following steps:

  1. Build the multithreaded JavaServerXA application, binding it with the Oracle8i Resource Manager, as described in "Using the WebLogic Enterprise JDBC/XA Driver" in Using the JDBC Drivers.

  2. In the UBBCONFIG, configure the OPENINFO parameter in the GROUPS section according to the definition of the XA parameter for the Oracle database. Listing 7-4 shows an example of an OPENINFO setting in a sample UBBCONFIG.

    Listing 7-4 OPENINFO Setting in Sample UBBCONFIG


    *GROUPS
    SYS_GRP
    LMID = SITE1
    GRPNO = 1
    BANK_GROUP1
    LMID = SITE1
    GRPNO = 2
    OPENINFO = "ORACLE_XA:Oracle_XA+Acc=P/scott/tiger+SesTm=100+LogDir=.+DbgFl=0x7+MaxCur=15+Threads=true"
    TMSNAME = TMS_ORA
    TMSCOUNT = 2


    For more information about the XA parameter, see the "A Oracle XA" chapter in the Fundamentals section of the Oracle Corporation Oracle8i Application Developer's Guide.

  3. If you want the JavaServerXA to be multithreaded, you must specify the -M option for the CLOPT parameter, which is defined in the JavaServerXA entry in the SERVERS section of the UBBCONFIG file.

    Note: For single-threaded JavaServerXA operation, skip this step.

    Listing 7-5 shows an example of JavaServerXA configured for multithreading in a sample UBBCONFIG.

    Listing 7-5 Multithreaded Server Configuration in Sample UBBCONFIG


    *SERVERS
    DEFAULT:
    RESTART = Y
    MAXGEN = 5
    ...
    JavaServerXA
    SRVGRP = BANK_GROUP1
    SRVID = 2
    SRVTYPE = JAVA
    CLOPT = "-A -- -M 10 BankApp.jar TellerFactory_1 bank_pool"
    RESTART = N


    To specify connection pooling, you need to specify SRVTYPE=JAVA in the SERVERS section.

  4. In the UBBCONFIG, configure the WebLogic Enterprise JDBC/XA driver in the WebLogic Enterprise JDBC Connection Pool, as described in "Using the WebLogic Enterprise JDBC/XA Driver" in Using the JDBC Drivers. Listing 7-6 shows an example of JDBC connection pool settings for a connection pool named bank_pool in a sample UBBCONFIG.

    Listing 7-6 JDBC Connection Pool Settings in Sample UBBCONFIG


    *JDBCCONNPOOLS
    bank_pool
    SRVGRP = BANK_GROUP1
    SRVID = 2
    DRIVER = "weblogic.jdbc20.oci815.Driver"
    URL = "jdbc:weblogic:oracle:beq-local"
    PROPS = "user=scott;password=tiger;server=Beq-Local"
    ENABLEXA = Y
    INITCAPACITY = 2
    MAXCAPACITY = 10
    CAPACITYINCR = 1
    CREATEONSTARTUP = Y


  5. Boot the JavaServerXA application, as described in "Using the WebLogic Enterprise JDBC/XA Driver" in Using the JDBC Drivers.

 


Implementing Distributed Transactions

This topic includes the following sections:

In addition to the fully supported examples supplied on the CD-ROM with this release of WebLogic Enterprise, the BEA WebLogic Enterprise team provides several unsupported code examples on a password protected Web site for WebLogic Enterprise customers. The code samples in this topic come from a version of the WebLogic Enterprise XA Bankapp sample application that is available from the unsupported samples WebLogic Enterprise Web site. The URL for the unsupported samples WebLogic Enterprise Web site is specified in the product Release Notes under "About This BEA WebLogic Enterprise Release" in the subsection "Unsupported Samples and Tools Web Page."

This application is different from the one described in the Bankapp Sample Using XA in the WebLogic Enterprise online documentation.

Note: This topic does not attempt to fully describe this sample application. It merely uses code fragments to illustrate the use of the JDBC/XA driver in a CORBA application.

Importing Packages

Listing 7-7 shows the packages that the application imports. In particular, note that:

Initializing the TransactionCurrent Object Reference

Listing 7-8 shows initializing the TransactionCurrent object reference, which will be used by the Teller operations to start and stop transactions.

Listing 7-8 Initializing the TransactionCurrent Object Reference


static org.omg.CosTransactions.Current trans_cur_ref;

org.omg.CORBA.Object trans_cur_oref = TP.bootstrap().resolve_initial_references("TransactionCurrent");


Finding the Connection Pool via JNDI

Listing 7-9 shows finding the connection pool via JNDI. The connection pool name is registered on the server group and is passed in as a command-line parameter upon server startup. Subsequent database connections are obtained from this pool.

Listing 7-9 Finding the Connection Pool via JNDI


static DataSource pool;

...

public void get_connpool(String pool_name)
throws Exception
{
try {
javax.naming.Context ctx = new InitialContext();
pool = (DataSource)ctx.lookup("jdbc/" + pool_name);
}
catch (javax.naming.NamingException ex){
TP.userlog("Couldn't obtain JDBC connection pool: " + pool_name);
throw ex;
}
}
}


Setting Up XA Distributed Transactions

Listing 7-10 shows setting up XA distributed transactions by calling the open_xa_rm method (in server.initialize) and obtaining a reference to the TransactionCurrent object.

Note: This step is required for CORBA applications but not for EJB or RMI applications.

Listing 7-10 Setting Up XA Distributed Transactions


TP.open_xa_rm();

org.omg.CORBA.Object trans_cur_oref = TP.bootstrap().resolve_initial_references("TransactionCurrent");

trans_cur_ref = org.omg.CosTransactions.CurrentHelper.narrow(trans_cur_oref);


Performing a Distributed Transaction

Listing 7-11 shows a complete distributed transaction that involves the transfer of money from one bank account to another.

Sequence of Tasks

The application performs the distributed application in the following sequence:

  1. The application calls the begin method to start the transaction.

  2. The application performs the following database operations:

  3. The application updates balances.

  4. The application catches any exceptions thrown during the database operations.

  5. The application closes the distributed transaction and updates teller statistics.

The withdraw Method

Listing 7-12 shows the withdraw method that is invoked in Listing 7-11. The withdraw method shows accessing the database to withdraw money from the specified account.

Listing 7-12 withdraw method


  public float withdraw(int accountID, float amount)
throws AccountRecordNotFound,
IOException,
InsufficientFunds,
TellerInsufficientFunds
{
boolean success = false;

try {
if (!transferInProgress) {
// This is just a plain withdrawal; it is NOT a transfer.

// Increment the number of requests that this teller
// has received.
tellerStats.totalTellerRequests += 1;

// Decrement the balance left in the Teller's ATM machine.
tellerStats.totalTellerBalance -= amount;

// Begin the global transaction.
BankAppServerImpl.trans_cur_ref.begin();

// Check to see if the minimum TELLER threshold balance
// has not been reached; if so, amount will be added back in
// in the finally clause.
if (tellerStats.totalTellerBalance < MinTellerBalance)
throw new TellerInsufficientFunds();
}

AccountDataHolder accountDataHolder =
new AccountDataHolder(new AccountData());
accountDataHolder.value.accountID = accountID;
accountDataHolder.value.balance = -amount;

// Withdraw the money from the account.
theDBAccess_ref.update_account(accountDataHolder);
success = true;
return(accountDataHolder.value.balance);
}
catch (AccountRecordNotFound e) {
throw e;
}
catch (InsufficientFunds e) {
throw e;
}
catch (TellerInsufficientFunds e) {
throw e;
}
catch (DataBaseException e) {
throw new IOException();
}
catch(Exception e) {
TP.userlog("Exception caught in withdraw(): "
+ e.getMessage());
e.printStackTrace();
throw new org.omg.CORBA.INTERNAL();
}
finally {
// Terminate the transaction and update the Teller statistics.
if (!transferInProgress) {
try {
if (success) {
tellerStats.totalTellerSuccess += 1;
BankAppServerImpl.trans_cur_ref.commit(true);
} else {
tellerStats.totalTellerFail += 1;
tellerStats.totalTellerBalance += amount;
BankAppServerImpl.trans_cur_ref.rollback();
}
}
catch(Exception e) {
TP.userlog("Unexpected Exception thrown during commit or rollback: " + e.getMessage());
e.printStackTrace();
throw new org.omg.CORBA.INTERNAL();
}
}
}
}


The deposit Method

Listing 7-13 shows the deposit method that is invoked in Listing 7-11. The deposit method shows accessing the database deposit money to the specified account.

Listing 7-13 deposit method