Writing a bean invocation so that a global transaction is suspended when a bean with transaction attribute RequiresNew is called from a global transaction
 Technote (troubleshooting)
 
Problem(Abstract)
With the following scenario:

Session Bean 1 (Bean Managed Transaction) contains plain JDBC code together with a call to Session Bean 2 which is part of a different application. Session Bean 1 uses only the one data source. Local Session Bean 2 (Container Managed Transaction) runs with transaction attribute RequiresNew. If Session Bean 2 is remote, the transaction attribute can be Requires or RequiresNew.

Configuring the data source used by Session Bean 1 as being non-XA and having Session Bean 2 in a remote Application Server results in the following errors being logged by the Application Server running Session Bean 1:

Ý6/23/04 13:52:43:750 CEST¨ 58422736 LocalTransact E J2CA0023E: A two phase XA operation, prepare, was invoked. This resource adapter from datasource jdbc/IVP does not support two phase processing.

Ý6/23/04 13:52:43:766 CEST¨ 58422736 OnePhaseResou u Encountered an XA resource error during an XA prepare operation: error code: XAER_PROTO javax.transaction.xa.XAException
at com.ibm.ejs.j2c.LocalTransactionWrapper.prepare(LocalTransactionWrapper.java:765)
at com.ibm.ejs.jts.jta.onephase.OnePhaseResourceImpl.prepare(OnePhaseResourceImpl.java:273)
 
Cause
Because the transaction is distributed (session bean 1 uses two connections, one for its data source and one for the other session bean), IBM® WebSphere® Application Server employs a two-phase commit protocol. For remote Enterprise JavaBeans™ calls, XA is automatically required. All resources used in the transaction must be capable of supporting the two-phase protocol; that is, they must be XA-enabled. The J2CA0023E occurs because the resource involved is not XA-capable.
 
Resolving the problem
The preferred solution for this problem is to configure the data source for session bean 1 with an XA-capable driver.


If it is not possible to use XA, the first session bean must have the following code technique used to get the first transaction properly suspended when the second session bean is called.


The idea behind the mechanism is to suspend the global transaction before issuing the remote call, then to resume the transaction after the remote call ends. The preInvoke method is called just before the remote method (session bean method) is called, and then the postInvoke() method is called after the remote method returns. This sequence of calls can be made any number of times before the UserTransaction.commit() call is made.

Note: The example refers to a remote method. It does not actually have to be remote; this mechanism works for both local and remote calls.

There is a mechanism to suspend a global transaction using a supported SPI.

In the program calling the remote EJB, do this once:

com.ibm.ws.extensionhelper.ExtensionHelper extHelper =
(com.ibm.ws.extensionhelper.ExtensionHelper)InitialContext.lookup
("services:websphere/ExtensionHelper");
com.ibm.ws.extensionhelper.extHelper.TransactionControl tranControl =
extHelper.getTransactionControl();

// Wrap work with TransactionControl preInvoke/postInvoke to execute
// outside current UOW.
try
{
// Suspends current global or local UOW. See below for flag settings com.ibm.ws.extensionhelper.extHelper.TxHandle txHandle =

tranControl.preInvoke(false, true) ;
/**************************************************************************************
Parameters for the preInvoke are as follows:
* Start a transaction, behavior will be decided by depending on
the input
* false, false, participate in a global transaction if one active
or start a new global transaction
* false, true, start a new global transaction, suspend any
existing global transaction
* true, false, start a new local transaction, suspend any other
transaction
* true, true, Error
****************************************************************************************/

// any work performed here is now in a new local UOW (i.e., outside a transaction) that will // be ended by postInvoke
}
finally
{
tranControl.postInvoke(txHandle) ; // resumes previous global or local UOW
}



Important: This mechanism gives you the outcome desired because the invoked session bean has a transaction attribute of requiresNew on the remote request. If Session Bean 2 is using Required for the transaction attribute, using this technique causes the JDBC and EJB operations to not roll back together if a failure occurs in the new transaction. This is because these are now separate transactions.

This means that the application programmer has to write the application to explicitly rollback any operations in the initial transaction that are dependent on the new transaction.

 
 
Cross Reference information
Segment Product Component Platform Version Edition
Application Servers Runtimes for Java Technology Java SDK
 
Product Alias/Synonym
WAS
 
 
 


Document Information


Product categories: Software > Application Servers > Distributed Application & Web Servers > WebSphere Application Server > Java Transaction Service (JTS)
Operating system(s): Windows
Software version: 5.1
Software edition:
Reference #: 1176727
IBM Group: Software Group
Modified date: Aug 16, 2004