The Transaction Service

WebLogic Server provides a transaction service that allows J2EE applications to manage their own transaction boundaries. WebLogic's transaction service supports multithreaded clients i.e., a client can make concurrent requests for transactions in multiple threads. WebLogic Server implements flat transactions, which means that multiple transactions cannot be associated with the same thread at the same time. WebLogic supports distributed transactions that may span multiple WebLogic servers, clusters, and even domains.

The EJB container uses WebLogic's transaction service to coordinate transactions across EJB components. EJBs that support bean-managed transactions and J2EE applications both use the JTA to explicitly manage their own transactions. J2EE clients can obtain the UserTransaction and TransactionManager objects from the JNDI tree and use these interfaces to demarcate their transaction boundaries. This allows lightweight clients to begin and commit transactions, and delegate the actual responsibility of coordinating the transaction to the remote transaction manager running on WebLogic Server.

6.3.1 Using JTA Transactions

The JTA defines the contract between the transaction manager and all resources involved in a distributed transaction i.e., the application, the application server, and the resource manager. It allows you to coordinate updates to multiple resources in a safe, elegant way, regardless of the transaction manager. The transaction manager is the standard façade to the transaction service. It manages the transaction boundaries on behalf of the J2EE applications. Ideally, a J2EE application should use the javax.transaction.UserTransaction interface to create a new transaction context. You can use the JTA transactions from within a J2EE client application or a server-side component, such as a servlet, a JMS message consumer, or any EJB that supports bean-managed transactions.

Here's an example that illustrates how you can use JTA transactions from within a servlet:

public void doPost(HttpServletRequest req, HttpServletResponse res) 
 throws ServletException, IOException { 
 Connection con = null;
 Statement st = null;
 UserTransaction tx = null;

 try {
 InitialContext ic = new InitialContext( );

 //get reference to XA-aware data source(s) from JNDI tree
 DataSource db1 = ic.lookup("java:comp/env/jdbc/xads1");
 DataSource db2 = ic.lookup("java:comp/env/jdbc/xads2");

 tx = (UserTransaction) ic.lookup("java:comp/UserTransaction");
 tx.begin( ); //start a new transaction

 //update some table in db1
 con = db1.getConnection( );
 st = con.createStatement( );
 st.executeUpdate("update foo ...");
 st.close( );

 //update some table in db2
 con2 = db2.getConnection( );
 st = con2.createStatement( );
 st.executeUpdate("delete from foobar ...");
 st.close( );

 tx.commit( ); //commit all changes

 //indicate success to client browser
 } catch (Exception e) {
 if (tx != null) tx.rollback( ); //rollback current transaction
 throw new ServletException(e);
 } finally {
 //release all db resources
 try {
 if (con != null) con.close( );
 if (con2 != null) con2.close( );
 }
 catch (Exception ignored) {}
 }
}

Unlike with EJBs, where you can use the EJBContext object to acquire a UserTransaction object, a servlet needs to look it up in the JNDI tree. WebLogic Server makes the UserTransaction object available to all application components in the JNDI tree under java:comp/UserTransaction. You then can invoke the begin( ) method to initiate a transaction, and later the commit( ) method to indicate that all updates may be committed. If an error occurs during the lifetime of the transaction, you can invoke the rollback( ) method to indicate that the transaction must be aborted.

If an external client uses JTA transactions, the only change is in the way you obtain the UserTransaction object:

Context ctx = null;

Hashtable env = new Hashtable( );
env.put(Context.INITIAL_CONTEXT_FACTORY, 
 "weblogic.jndi.WLInitialContextFactory");
env.put(Context.PROVIDER_URL, "t3://localhost:7001"); 
env.put(Context.SECURITY_PRINCIPAL, "joebloggs");
env.put(Context.SECURITY_CREDENTIALS, "somepassword");
 
ctx = new InitialContext(env);
UserTransaction tx = (UserTransaction)
 ctx.lookup("javax.transaction.UserTransaction");

This code sample shows how an external client needs to provide additional information, such as the T3 URL of a running server, and details of the WebLogic principal who is authorized to access the specified branch of the JNDI tree. For an external client, WebLogic Server makes the UserTransaction object available in the JNDI tree under javax.transaction.UserTransaction.

6.3.2 Using XA Versus Non-XA Drivers in JTA Transactions

Recall how a JDBC connection pool can be configured using either an XA-aware JDBC driver or a non-XA driver. If an XA-aware driver is used, the XA-aware data source associated with this connection pool can participate fully in distributed transactions. If the connection pool has been configured using a non-XA JDBC driver, the associated data source can still participate in JTA transactions, provided you instruct WebLogic to emulate two-phase commit for the data source. Thus, an XA-aware data source configured using a pool of non-XA connections can honor distributed transactions only if you've enabled two-phase commit emulation on the data source. You do have to pay a price for this emulation, though.

First, WebLogic manages connections from a non-XA driver and an XA-aware driver in different ways. When a non-XA connection is involved in a distributed transaction, WebLogic holds onto the physical JDBC connection for the duration of the transaction until it is committed or rolled back. Thus, for a non-XA pool, the number of concurrent transactions is limited by the size of the connection pool. XA connections, on the other hand, are more flexible. In this case, WebLogic doesn't need to hold onto the physical JDBC connection until the transaction completes. Clearly, an XA pool is more scalable because the number of active transactions isn't limited by the size of the pool.

Second, a distributed transaction can handle only one XA-aware data source configured for two-phase commit emulation. This means that WebLogic cannot manage multiple XA-aware data sources enabled with the two-phase commit emulation within the same JTA transaction. If you attempt to enlist non-XA connections obtained from two (or more) XA-aware data sources configured for two-phase commit emulation within a JTA transaction, WebLogic will throw an SQLException.

You must adhere to some programming guidelines when using a XA-aware data source:

  • By default, auto-commit is disabled for all connections obtained from the XA-aware data source. So, you must not attempt to enable auto-commit on any connections obtained from the XA-aware data source. For example, a call to the Connection.setAutoCommit(true) method within an existing transaction context will throw an SQLException.
  • In addition, if a JTA transaction is currently active, you must not commit any local transactions on the actual Connection itself. This means that you must not invoke the commit( ) or rollback( ) methods on the Connection object while in the middle of a distributed transaction. If you're using a JDBC 3.0-compliant driver, you must not invoke the setSavePoint( ) method on the Connection object either.

Finally, if the XA-aware data source is configured to use a non-XA pool of connections, the connection obtained from the data source will be enlisted in a distributed transaction only if you obtain the connection after the transaction has been initiated. Thus, for any XA-aware data source using two-phase commit emulation, you should request a connection from the data source only after beginning a new transaction context:

 InitialContext ctx = new InitialContext( );

 //get reference to XA-aware data source from JNDI tree
 DataSource ds = ic.lookup("java:comp/env/jdbc/txds");

 tx = (UserTransaction) ic.lookup("java:comp/UserTransaction");
 tx.begin( ); //start a new transaction

 //now create a connection so that it can be enlisted in the transaction
 Connection con = ds.getConnection( );
 ...

However, if the XA-aware data source has been configured using an XA-aware JDBC driver, it makes no difference whether you acquire the Connection object before or after the JTA transaction has been initiated. Also, ensure that you close an XA connection after the transaction has been committed. In fact, we recommend that you create and release XA connections from outside the scope of a transaction context. This way, an XA connection is enlisted for the duration of the JTA transaction, until it has been committed.

6.3.2.1 Data integrity problems with two-phase commit emulation

You should use two-phase commit emulation with caution because it is not a perfect strategy and can result in some data integrity problems. Two-phase commit emulation is designed to ensure that the non-XA connection always succeeds in the prepare phase of the distribution transaction. The local transaction on the non-XA connection commits only when all other XA-aware resources involved in the distributed transaction are ready to commit. Only when this commit on the non-XA connection succeeds does the overall distributed transaction commit its work. If any of the other XA-aware resources involved in the transaction need to roll back, the overall distributed transaction as well as the local transaction on the non-XA connection also roll back.

If the commit or rollback on the local transaction fails, a heuristic error results, which may lead to data integrity errors. A similar error can occur if, say, a network error occurs after a commit message has been sent to all XA resources in the distributed transaction. The transaction manager will automatically abort the commit on all participating resources, but the non-XA resource will have committed its work, thereby resulting in a heuristic completion. For these reasons, ensure that your applications can tolerate potential heuristic completions when using an XA-aware data source configured for two-phase commit emulation.

6.3.3 WebLogic Extensions to the JTA

The JTA defines the following interfaces:

  • The UserTransaction interface that allows a J2EE application to explicitly control transaction boundaries
  • The TransactionManager interface that allows WebLogic to manage EJBs that support container-managed transactions
  • The Status interface that encapsulates information about the current status of a transaction
  • The Synchronization interface that allows interested parties to be notified before and after the transaction
  • Various interfaces that allow the transaction manager to work with XA-compliant resources (XAResource interface) and obtain the Xid interface

WebLogic Server extends the capabilities of the JTA interfaces in the following ways:

  • It makes the TransactionManager interface available to external clients and EJBs through the JNDI tree. A J2EE client or an EJB that supports bean-managed transactions can then suspend the transaction associated with the current thread and later resume it (just like the EJB container).
  • WebLogic's extension to the TransactionManager interface allows you to register (or deregister) XA-compliant resources, force suspension of the transaction for the current thread, and force resumption of a suspended transaction.
  • It extends the Transaction interface by enabling you to get the transaction identifier, access transaction properties, specify a reason for the rollback, and determine whether the transaction has timed out.
  • It provides a convenience helper class (weblogic.transaction.TxHelper) that lets you access the transaction context or the transaction manager associated with the current thread.

Refer to the API documentation for a more detailed explanation of these extensions.

Introduction

Web Applications

Managing the Web Server

Using JNDI and RMI

JDBC

Transactions

J2EE Connectors

JMS

JavaMail

Using EJBs

Using CMP and EJB QL

Packaging and Deployment

Managing Domains

Clustering

Performance, Monitoring, and Tuning

SSL

Security

XML

Web Services

JMX

Logging and Internationalization

SNMP



WebLogic. The Definitive Guide
WebLogic: The Definitive Guide
ISBN: 059600432X
EAN: 2147483647
Year: 2003
Pages: 187

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net