Author: dain Date: Tue Oct 12 17:38:55 2004 New Revision: 54714 Modified: geronimo/trunk/maven.xml geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java Log: Fixed problem with cmt transaction commit and rollback
Modified: geronimo/trunk/maven.xml ============================================================================== --- geronimo/trunk/maven.xml (original) +++ geronimo/trunk/maven.xml Tue Oct 12 17:38:55 2004 @@ -117,8 +117,8 @@ <goal name="m:default" prereqs="m:init"> <!-- don't run the active mq tests they take way too long and don't complete successfully --> <u:available file="${basedir}/activemq"> - <mkdir dir="${basedir}/activemq/target/test-reports/"/> - <ant:touch file="${basedir}/activemq/target/test-reports/tstamp"/> + <mkdir dir="${basedir}/activemq/modules/core/target/test-reports/"/> + <ant:touch file="${basedir}/activemq/modules/core/target/test-reports/tstamp"/> </u:available> <j:set var="goal" value="default"/> <attainGoal name="multiproject:goal"/> Modified: geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java ============================================================================== --- geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java (original) +++ geronimo/trunk/modules/connector/src/test/org/apache/geronimo/connector/deployment/RAR_1_5ConfigBuilderTest.java Tue Oct 12 17:38:55 2004 @@ -199,7 +199,7 @@ assertNotNull(activationSpecInfo); GBeanInfo activationSpecGBeanInfo = activationSpecInfo.getActivationSpecGBeanInfo(); List attributes = activationSpecGBeanInfo.getPersistentAttributes(); - assertEquals(3, attributes.size()); + assertEquals(2, attributes.size()); //startRecursive can only be invoked if GBean is stopped. kernel.stopGBean(objectName); Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java ============================================================================== --- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java (original) +++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/DefaultInstanceContext.java Tue Oct 12 17:38:55 2004 @@ -21,8 +21,6 @@ import java.util.Map; import java.util.Set; -import org.apache.geronimo.transaction.InstanceContext; - /** * Simple implementation of ComponentContext satisfying invariant. Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java ============================================================================== --- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java (original) +++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/ContainerTransactionContext.java Tue Oct 12 17:38:55 2004 @@ -21,7 +21,6 @@ import javax.transaction.HeuristicRollbackException; import javax.transaction.InvalidTransactionException; import javax.transaction.NotSupportedException; -import javax.transaction.RollbackException; import javax.transaction.Status; import javax.transaction.SystemException; import javax.transaction.Transaction; @@ -59,61 +58,117 @@ threadAssociated = true; } - /** - * TODO the exceptions thrown here are not all correct. Don't throw a RollbackException after - * a successful commit...?? - * - * @throws javax.transaction.HeuristicMixedException - * - * @throws javax.transaction.HeuristicRollbackException - * - * @throws javax.transaction.RollbackException - * - * @throws javax.transaction.SystemException - * - */ - public void commit() throws HeuristicMixedException, HeuristicRollbackException, RollbackException, SystemException { + public void commit() throws HeuristicMixedException, HeuristicRollbackException, SystemException { + boolean wasCommitted = false; try { - try { - flushState(); - } catch (Throwable t) { - try { - txnManager.rollback(); - } catch (Throwable t1) { - log.error("Unable to roll back transaction", t1); - } - throw (RollbackException) new RollbackException("Could not flush state before commit").initCause(t); + if (checkRolledback()) { + return; } - try { - beforeCommit(); - } catch (Exception e) { - try { - txnManager.rollback(); - } catch (Throwable t1) { - log.error("Unable to roll back transaction", t1); - } - throw (RollbackException) new RollbackException("Could not flush state before commit").initCause(e); + + flushState(); + + if (checkRolledback()) { + return; } + + // todo we need to flush anyone enrolled during before and then call before on any flushed... + beforeCommit(); + + if (checkRolledback()) { + return; + } + txnManager.commit(); + wasCommitted = true; + } catch (Throwable t) { + rollbackAndThrow("Unable to commit container transaction", t); + } finally { try { - afterCommit(true); + afterCommit(wasCommitted); } catch (Exception e) { - try { - txnManager.rollback(); - } catch (Throwable t1) { - log.error("Unable to roll back transaction", t1); - } - throw (RollbackException) new RollbackException("Could not flush state before commit").initCause(e); + rollbackAndThrow("After commit of container transaction failed", e); + } finally { + connectorAfterCommit(); + transaction = null; } - } finally { - connectorAfterCommit(); - transaction = null; } } - public void rollback() throws SystemException { + private boolean checkRolledback() throws SystemException { + int status; try { + status = transaction.getStatus(); + } catch (SystemException e) { txnManager.rollback(); + throw e; + } + + if (status == Status.STATUS_MARKED_ROLLBACK) { + // we need to rollback + txnManager.rollback(); + return true; + } else if (status == Status.STATUS_ROLLEDBACK || + status == Status.STATUS_ROLLING_BACK) { + // already rolled back + return true; + } + return false; + } + + private void rollbackAndThrow(String message, Throwable throwable) throws HeuristicMixedException, HeuristicRollbackException, SystemException { + try { + // just incase there is a junk transaction on the thread + if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) { + txnManager.rollback(); + } + } catch (Throwable t) { + log.error("Unable to roll back transaction", t); + } + + if (throwable instanceof HeuristicMixedException) { + throw (HeuristicMixedException) throwable; + } else if (throwable instanceof HeuristicRollbackException) { + throw (HeuristicRollbackException) throwable; + } else if (throwable instanceof SystemException) { + throw (SystemException) throwable; + } else if (throwable instanceof Error) { + throw (Error) throwable; + } else if (throwable instanceof RuntimeException) { + throw (RuntimeException) throwable; + } else { + throw (SystemException) new SystemException(message).initCause(throwable); + } + } + + public void rollback() throws SystemException { + try { + try { + if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) { + txnManager.rollback(); + } + } finally { + try { + afterCommit(false); + } catch (Throwable e) { + try { + // just incase there is a junk transaction on the thread + if (txnManager.getStatus() != Status.STATUS_NO_TRANSACTION) { + txnManager.rollback(); + } + } catch (Throwable t1) { + log.error("Unable to roll back transaction", t1); + } + + if (e instanceof SystemException) { + throw (SystemException) e; + } else if (e instanceof Error) { + throw (Error) e; + } else if (e instanceof RuntimeException) { + throw (RuntimeException) e; + } + throw (SystemException) new SystemException("After commit of container transaction failed").initCause(e); + } + } } finally { connectorAfterCommit(); transaction = null; Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java ============================================================================== --- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java (original) +++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/context/TransactionContext.java Tue Oct 12 17:38:55 2004 @@ -21,20 +21,18 @@ import java.util.HashMap; import java.util.Iterator; import java.util.Map; - import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; import javax.transaction.InvalidTransactionException; -import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; import javax.transaction.Transaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.geronimo.transaction.InstanceContext; -import org.apache.geronimo.transaction.DoubleKeyedHashMap; import org.apache.geronimo.transaction.ConnectionReleaser; +import org.apache.geronimo.transaction.DoubleKeyedHashMap; +import org.apache.geronimo.transaction.InstanceContext; import org.tranql.cache.InTxCache; import org.tranql.cache.SimpleFlushStrategy; @@ -123,11 +121,25 @@ } protected void afterCommit(boolean status) throws Exception { - // @todo allow for enrollment during pre-commit + Throwable firstThrowable = null; ArrayList toFlush = new ArrayList(associatedContexts.values()); for (Iterator i = toFlush.iterator(); i.hasNext();) { InstanceContext context = (InstanceContext) i.next(); - context.afterCommit(status); + try { + context.afterCommit(status); + } catch (Throwable e) { + if (firstThrowable == null) { + firstThrowable = e; + } + } + } + + if (firstThrowable instanceof Error) { + throw (Error) firstThrowable; + } else if (firstThrowable instanceof Exception) { + throw (Exception) firstThrowable; + } else if (firstThrowable != null) { + throw (SystemException) new SystemException().initCause(firstThrowable); } } Modified: geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java ============================================================================== --- geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java (original) +++ geronimo/trunk/modules/transaction/src/java/org/apache/geronimo/transaction/manager/TransactionImpl.java Tue Oct 12 17:38:55 2004 @@ -88,7 +88,6 @@ } public synchronized void setRollbackOnly() throws IllegalStateException, SystemException { - log.info("in setRollbackOnly, txImpl", new Exception("stack trace")); switch (status) { case Status.STATUS_ACTIVE: case Status.STATUS_PREPARING: