Skip to content

Instantly share code, notes, and snippets.

@rmannibucau
Last active December 28, 2015 21:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rmannibucau/7564089 to your computer and use it in GitHub Desktop.
Save rmannibucau/7564089 to your computer and use it in GitHub Desktop.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.deltaspike.jpa.impl.transaction;
import org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy;
import javax.enterprise.context.Dependent;
import javax.enterprise.inject.Alternative;
import javax.interceptor.InvocationContext;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.transaction.Status;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
import java.lang.reflect.Method;
/**
* <p>{@link org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy} for using JTA transactions.
*/
@Dependent
@Alternative
@SuppressWarnings("UnusedDeclaration")
//TODO move to a separated ds-jta module and use @Specializes -> no additional config is needed
public class TransactionManagerTransactionStrategy implements TransactionStrategy
{
private static final String [] JNDI_LOCS = new String []{
"javax.transaction.TransactionManager", // weblogic
"java:/TransactionManager", // jboss, jrun, Geronimo
"java:/DefaultDomain/TransactionManager", // jrun too
"java:comp/pm/TransactionManager", // orion & oracle
"java:comp/TransactionManager", // generic
"java:appserver/TransactionManager", // GlassFish
"java:pm/TransactionManager", // borland
"aries:services/javax.transaction.TransactionManager", // Apache Aries
};
private static final String [] METHODS = new String[]{
"com.arjuna.jta.JTA_TransactionManager.transactionManager", // hp
"com.bluestone.jta.SaTransactionManagerFactory.SaGetTransactionManager",
"org.openejb.OpenEJB.getTransactionManager",
"com.sun.jts.jta.TransactionManagerImpl.getTransactionManagerImpl",
"com.inprise.visitransact.jta.TransactionManagerImpl."
+ "getTransactionManagerImpl", // borland
};
private static volatile TransactionManager transactionManager = null;
static
{
try
{
initTransactionManager();
}
catch (final IllegalStateException ise)
{
// no-op: try lazily
}
}
@Override
public Object execute(final InvocationContext invocationContext) throws Exception
{
boolean responsible = false;
Transaction tx = initTransactionManager().getTransaction();
if (tx == null)
{
transactionManager.begin();
tx = transactionManager.getTransaction();
responsible = true;
}
try
{
return invocationContext.proceed();
}
catch (final Exception th)
{
if (responsible)
{
tx.rollback();
}
throw th;
}
finally
{
if (responsible)
{
if (tx.getStatus() == Status.STATUS_ACTIVE)
{
tx.commit();
}
else
{
tx.rollback();
}
}
}
}
private static TransactionManager initTransactionManager() {
if (TransactionManagerTransactionStrategy.transactionManager != null)
{
return TransactionManagerTransactionStrategy.transactionManager;
}
TransactionManager transactionManager = null;
// try to find a jndi runtime
try {
final InitialContext context = new InitialContext();
for (final String jndi : JNDI_LOCS) {
try {
transactionManager = TransactionManager.class.cast(context.lookup(jndi));
} catch (final Throwable t) {
// no-op
}
if (transactionManager != null) {
break;
}
}
} catch (final NamingException ne) {
// no-op
}
// look for a method runtime
if (transactionManager == null) {
for (final String method : METHODS) {
final String clazz = method.substring(0, method.lastIndexOf('.'));
final String methodName = method.substring(method.lastIndexOf('.') + 1);
try {
final ClassLoader tccl = Thread.currentThread().getContextClassLoader();
final Method mtd = Class.forName(clazz, true, tccl).getMethod(methodName);
transactionManager = TransactionManager.class.cast(mtd.invoke(null));
} catch (final Throwable t) {
// no-op
}
if (transactionManager != null) {
break;
}
}
}
if (transactionManager == null)
{
throw new IllegalStateException("Can't find any transaction manager");
}
if (TransactionManagerTransactionStrategy.transactionManager == null)
{
TransactionManagerTransactionStrategy.transactionManager = transactionManager;
}
return transactionManager;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment