|
Spring Framework example source code file (OC4JJtaTransactionManager.java)
This example Spring Framework source code file (OC4JJtaTransactionManager.java) is included in the DevDaily.com
"Java Source Code
Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.
The Spring Framework OC4JJtaTransactionManager.java source code
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.transaction.jta;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.transaction.NotSupportedException;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.UserTransaction;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.util.ClassUtils;
/**
* Special {@link JtaTransactionManager} variant for Oracle OC4J (10.1.3 and higher).
* Supports the full power of Spring's transaction definitions on OC4J's
* transaction coordinator, <i>beyond standard JTA: transaction names
* and per-transaction isolation levels.
*
* <p>Uses OC4J's special begin(name) method to start a JTA transaction,
* in orderto make <b>Spring-driven transactions visible in OC4J's transaction
* monitor</b>. In case of Spring's declarative transactions, the exposed name will
* (by default) be the fully-qualified class name + "." + method name.
*
* <p>Supports a per-transaction isolation level through OC4J's corresponding
* <code>OC4JTransaction.setTransactionIsolation(int) method. This will
* apply the specified isolation level (e.g. ISOLATION_SERIALIZABLE) to all
* JDBC Connections that participate in the given transaction.
*
* <p>Automatically detects the available OC4J server version and adapts accordingly.
* Supports the "com.evermind.server" package in OC4J 10.1.3.2 as well as the
* "oracle.j2ee.transaction" package in later OC4J versions.
*
* <p>By default, the JTA UserTransaction and TransactionManager handles are
* fetched directly from OC4J's <code>TransactionUtility in 10.1.3.2+.
* This can be overridden by specifying "userTransaction"/"userTransactionName"
* and "transactionManager"/"transactionManagerName", passing in existing handles
* or specifying corresponding JNDI locations to look up.
*
* <p>Thanks to Oracle for donating the original version of this extended OC4J
* integration code to the Spring project!
*
* @author Paul Parkinson
* @author Juergen Hoeller
* @since 2.0.3
* @see org.springframework.transaction.TransactionDefinition#getName
* @see org.springframework.transaction.TransactionDefinition#getIsolationLevel
* @see oracle.j2ee.transaction.OC4JTransactionManager#begin(String)
* @see oracle.j2ee.transaction.OC4JTransaction#setTransactionIsolation
* @see oracle.j2ee.transaction.TransactionUtility
*/
public class OC4JJtaTransactionManager extends JtaTransactionManager {
private static final String TRANSACTION_UTILITY_CLASS_NAME =
"oracle.j2ee.transaction.TransactionUtility";
private static final String TRANSACTION_MANAGER_CLASS_NAME =
"oracle.j2ee.transaction.OC4JTransactionManager";
private static final String TRANSACTION_CLASS_NAME =
"oracle.j2ee.transaction.OC4JTransaction";
private static final String FALLBACK_TRANSACTION_MANAGER_CLASS_NAME =
"com.evermind.server.ApplicationServerTransactionManager";
private static final String FALLBACK_TRANSACTION_CLASS_NAME =
"com.evermind.server.ApplicationServerTransaction";
private Method beginWithNameMethod;
private Method setTransactionIsolationMethod;
public void afterPropertiesSet() throws TransactionSystemException {
super.afterPropertiesSet();
loadOC4JTransactionClasses();
}
protected UserTransaction retrieveUserTransaction() throws TransactionSystemException {
try {
Class transactionUtilityClass = getClass().getClassLoader().loadClass(TRANSACTION_UTILITY_CLASS_NAME);
Method getInstanceMethod = transactionUtilityClass.getMethod("getInstance", new Class[0]);
Object transactionUtility = getInstanceMethod.invoke(null, new Object[0]);
logger.debug("Retrieving JTA UserTransaction from OC4J TransactionUtility");
Method getUserTransactionMethod =
transactionUtility.getClass().getMethod("getOC4JUserTransaction", new Class[0]);
return (UserTransaction) getUserTransactionMethod.invoke(transactionUtility, new Object[0]);
}
catch (ClassNotFoundException ex) {
logger.debug("Could not find OC4J 10.1.3.2 TransactionUtility: " + ex);
// Return null to make the superclass perform its standard J2EE lookup,
// which will work on earlier OC4J versions.
return null;
}
catch (InvocationTargetException ex) {
throw new TransactionSystemException(
"OC4J's TransactionUtility.getOC4JUserTransaction() method failed", ex.getTargetException());
}
catch (Exception ex) {
throw new TransactionSystemException(
"Could not invoke OC4J's TransactionUtility.getOC4JUserTransaction() method", ex);
}
}
private void loadOC4JTransactionClasses() throws TransactionSystemException {
// Find available OC4J API (in "oracle.j2ee.transaction" or "com.evermind.server")
Class transactionManagerClass = null;
Class transactionClass = null;
try {
transactionManagerClass = getClass().getClassLoader().loadClass(TRANSACTION_MANAGER_CLASS_NAME);
transactionClass = getClass().getClassLoader().loadClass(TRANSACTION_CLASS_NAME);
}
catch (ClassNotFoundException ex) {
try {
transactionManagerClass = getClass().getClassLoader().loadClass(FALLBACK_TRANSACTION_MANAGER_CLASS_NAME);
transactionClass = getClass().getClassLoader().loadClass(FALLBACK_TRANSACTION_CLASS_NAME);
}
catch (ClassNotFoundException ex2) {
throw new TransactionSystemException(
"Could not initialize OC4JJtaTransactionManager because OC4J API classes are not available", ex);
}
}
// Cache reflective Method references for later use.
if (transactionManagerClass.isInstance(getUserTransaction())) {
this.beginWithNameMethod = ClassUtils.getMethodIfAvailable(
transactionManagerClass, "begin", new Class[] {String.class});
this.setTransactionIsolationMethod = ClassUtils.getMethodIfAvailable(
transactionClass, "setTransactionIsolation", new Class[] {int.class});
logger.info("Support for OC4J transaction names and isolation levels available");
}
else {
logger.info("Support for OC4J transaction names and isolation levels not available");
}
}
protected void doJtaBegin(JtaTransactionObject txObject, TransactionDefinition definition)
throws NotSupportedException, SystemException {
int timeout = determineTimeout(definition);
applyTimeout(txObject, timeout);
// Apply transaction name, if any, through the extended OC4J transaction begin method.
if (this.beginWithNameMethod != null && definition.getName() != null) {
/*
oracle.j2ee.transaction.OC4JTransactionManager otm = (oracle.j2ee.transaction.OC4JTransactionManager) ut;
otm.begin(definition.getName());
*/
try {
this.beginWithNameMethod.invoke(txObject.getUserTransaction(), new Object[] {definition.getName()});
}
catch (InvocationTargetException ex) {
throw new TransactionSystemException(
"OC4J's UserTransaction.begin(String) method failed", ex.getTargetException());
}
catch (Exception ex) {
throw new TransactionSystemException(
"Could not invoke OC4J's UserTransaction.begin(String) method", ex);
}
}
else {
// No OC4J UserTransaction available or no transaction name specified
// -> standard JTA begin call.
txObject.getUserTransaction().begin();
}
// Specify isolation level, if any, through the corresponding OC4J transaction method.
if (this.setTransactionIsolationMethod != null) {
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
try {
Transaction tx = getTransactionManager().getTransaction();
/*
oracle.j2ee.transaction.OC4JTransaction otx = (oracle.j2ee.transaction.OC4JTransaction) tx;
otx.setTransactionIsolation(definition.getIsolationLevel());
*/
Integer isolationLevel = new Integer(definition.getIsolationLevel());
this.setTransactionIsolationMethod.invoke(tx, new Object[] {isolationLevel});
}
catch (InvocationTargetException ex) {
throw new TransactionSystemException(
"OC4J's Transaction.setTransactionIsolation(int) method failed", ex.getTargetException());
}
catch (Exception ex) {
throw new TransactionSystemException(
"Could not invoke OC4J's Transaction.setTransactionIsolation(int) method", ex);
}
}
}
else {
applyIsolationLevel(txObject, definition.getIsolationLevel());
}
}
public Transaction createTransaction(String name, int timeout) throws NotSupportedException, SystemException {
if (this.beginWithNameMethod != null && name != null) {
UserTransaction ut = getUserTransaction();
if (timeout >= 0) {
ut.setTransactionTimeout(timeout);
}
try {
this.beginWithNameMethod.invoke(ut, new Object[] {name});
}
catch (InvocationTargetException ex) {
if (ex.getTargetException() instanceof NotSupportedException) {
throw (NotSupportedException) ex.getTargetException();
}
else if (ex.getTargetException() instanceof SystemException) {
throw (SystemException) ex.getTargetException();
}
else if (ex.getTargetException() instanceof RuntimeException) {
throw (RuntimeException) ex.getTargetException();
}
else {
throw new SystemException(
"OC4J's begin(String) method failed with an unexpected error: " + ex.getTargetException());
}
}
catch (Exception ex) {
throw new SystemException("Could not invoke OC4J's UserTransaction.begin(String) method: " + ex);
}
return getTransactionManager().getTransaction();
}
else {
// No name specified - standard JTA is sufficient.
return super.createTransaction(name, timeout);
}
}
}
Other Spring Framework examples (source code examples)
Here is a short list of links related to this Spring Framework OC4JJtaTransactionManager.java source code file:
|