You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2006/09/12 01:12:00 UTC
svn commit: r442384 - in
/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager:
Closeable.java TransactionImpl.java TransactionManagerImpl.java
Author: djencks
Date: Mon Sep 11 16:11:59 2006
New Revision: 442384
URL: http://svn.apache.org/viewvc?view=rev&rev=442384
Log:
GERONIMO-2349 jta 1.1 support methods in jta 1.0.1B tx manager, with extension jars for jta 1.1 support
Added:
geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java (with props)
Modified:
geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
Added: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java?view=auto&rev=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java (added)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java Mon Sep 11 16:11:59 2006
@@ -0,0 +1,27 @@
+/**
+ *
+ * Copyright 2006 The Apache Software Foundation
+ *
+ * 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.apache.geronimo.transaction.manager;
+
+/**
+ * @version $Rev:$ $Date:$
+ */
+public interface Closeable {
+
+ void close();
+
+}
Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
svn:keywords = Date Revision
Propchange: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/Closeable.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java?view=diff&rev=442384&r1=442383&r2=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java (original)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionImpl.java Mon Sep 11 16:11:59 2006
@@ -18,12 +18,14 @@
package org.apache.geronimo.transaction.manager;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
+
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.RollbackException;
@@ -34,6 +36,7 @@
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
+import javax.ejb.EJBException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -57,6 +60,10 @@
private int status = Status.STATUS_NO_TRANSACTION;
private Object logMark;
+ private final Map resources = new HashMap();
+ private Synchronization interposedSynchronization;
+ private final Map entityManagers = new HashMap();
+
TransactionImpl(XidFactory xidFactory, TransactionLog txnLog, long transactionTimeoutMilliseconds) throws SystemException {
this(xidFactory.createXid(), xidFactory, txnLog, transactionTimeoutMilliseconds);
}
@@ -87,11 +94,38 @@
this.timeout = Long.MAX_VALUE;
}
- public synchronized int getStatus() throws SystemException {
+ public synchronized int getStatus() {
return status;
}
- public synchronized void setRollbackOnly() throws IllegalStateException, SystemException {
+ public Object getResource(Object key) {
+ return resources.get(key);
+ }
+
+ public boolean getRollbackOnly() {
+ return status == Status.STATUS_MARKED_ROLLBACK;
+ }
+
+ public Object getTransactionKey() {
+ return xid;
+ }
+
+ public int getTransactionStatus() {
+ return status;
+ }
+
+ public void putResource(Object key, Object value) {
+ if (key == null) {
+ throw new NullPointerException("You must supply a non-null key for putResource");
+ }
+ resources.put(key, value);
+ }
+
+ public void registerInterposedSynchronization(Synchronization synchronization) {
+ interposedSynchronization = synchronization;
+ }
+
+ public synchronized void setRollbackOnly() throws IllegalStateException {
switch (status) {
case Status.STATUS_ACTIVE:
case Status.STATUS_PREPARING:
@@ -171,7 +205,7 @@
//we know nothing about this XAResource or resource manager
Xid branchId = xidFactory.createBranch(xid, resourceManagers.size() + 1);
xaRes.start(branchId, XAResource.TMNOFLAGS);
- activeXaResources.put(xaRes, addBranchXid(xaRes, branchId));
+ activeXaResources.put(xaRes, addBranchXid(xaRes, branchId));
return true;
} catch (XAException e) {
log.warn("Unable to enlist XAResource " + xaRes + ", errorCode: " + e.errorCode, e);
@@ -222,23 +256,19 @@
beforePrepare();
try {
- boolean timedout = false;
- if (TransactionTimer.getCurrentTime() > timeout)
- {
- status = Status.STATUS_MARKED_ROLLBACK;
- timedout = true;
- }
+ boolean timedout = false;
+ if (TransactionTimer.getCurrentTime() > timeout) {
+ status = Status.STATUS_MARKED_ROLLBACK;
+ timedout = true;
+ }
if (status == Status.STATUS_MARKED_ROLLBACK) {
rollbackResources(resourceManagers);
- if(timedout)
- {
- throw new RollbackException("Transaction timout");
- }
- else
- {
- throw new RollbackException("Unable to commit: transaction marked for rollback");
- }
+ if (timedout) {
+ throw new RollbackException("Transaction timout");
+ } else {
+ throw new RollbackException("Unable to commit: transaction marked for rollback");
+ }
}
synchronized (this) {
if (status == Status.STATUS_ACTIVE) {
@@ -256,7 +286,6 @@
// resourceManagers is now immutable
}
-
// no-phase
if (resourceManagers.size() == 0) {
synchronized (this) {
@@ -400,7 +429,6 @@
}
}
-
// decision time...
boolean willCommit;
synchronized (this) {
@@ -471,9 +499,17 @@
Synchronization synch;
synchronized (this) {
if (i == syncList.size()) {
+ if (interposedSynchronization != null) {
+ synch = interposedSynchronization;
+ i++;
+ } else {
+ return;
+ }
+ } else if (i == syncList.size() + 1) {
return;
+ } else {
+ synch = (Synchronization) syncList.get(i++);
}
- synch = (Synchronization) syncList.get(i++);
}
try {
synch.beforeCompletion();
@@ -488,6 +524,13 @@
private void afterCompletion() {
// this does not synchronize because nothing can modify our state at this time
+ if (interposedSynchronization != null) {
+ try {
+ interposedSynchronization.afterCompletion(status);
+ } catch (Exception e) {
+ log.warn("Unexpected exception from afterCompletion; continuing", e);
+ }
+ }
for (Iterator i = syncList.iterator(); i.hasNext();) {
Synchronization synch = (Synchronization) i.next();
try {
@@ -497,6 +540,10 @@
continue;
}
}
+ for (Iterator i = entityManagers.values().iterator(); i.hasNext();) {
+ Closeable entityManager = (Closeable) i.next();
+ entityManager.close();
+ }
}
private void endResources() {
@@ -579,7 +626,7 @@
txnLog.commit(xid, logMark);
} catch (LogException e) {
log.error("Unexpected exception logging commit completion for xid " + xid, e);
- throw (SystemException)new SystemException("Unexpected error logging commit completion for xid " + xid).initCause(e);
+ throw (SystemException) new SystemException("Unexpected error logging commit completion for xid " + xid).initCause(e);
}
}
synchronized (this) {
@@ -634,6 +681,17 @@
return manager;
}
+ public Object getEntityManager(String persistenceUnit) {
+ return entityManagers.get(persistenceUnit);
+ }
+
+ public void setEntityManager(String persistenceUnit, Object entityManager) {
+ Object oldEntityManager = entityManagers.put(persistenceUnit, entityManager);
+ if (oldEntityManager != null) {
+ throw new EJBException("EntityManager " + oldEntityManager + " for persistenceUnit " + persistenceUnit + " already associated with this transaction " + xid);
+ }
+ }
+
private static class TransactionBranch implements TransactionBranchInfo {
private final XAResource committer;
private final Xid branchId;
@@ -653,7 +711,7 @@
public String getResourceName() {
if (committer instanceof NamedXAResource) {
- return ((NamedXAResource)committer).getName();
+ return ((NamedXAResource) committer).getName();
} else {
throw new IllegalStateException("Cannot log transactions unles XAResources are named! " + committer);
}
Modified: geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java?view=diff&rev=442384&r1=442383&r2=442384
==============================================================================
--- geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java (original)
+++ geronimo/server/trunk/modules/geronimo-transaction/src/main/java/org/apache/geronimo/transaction/manager/TransactionManagerImpl.java Mon Sep 11 16:11:59 2006
@@ -23,12 +23,14 @@
import java.util.Iterator;
import java.util.List;
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.Status;
+import javax.transaction.Synchronization;
import javax.transaction.SystemException;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
@@ -121,7 +123,7 @@
return new ArrayList(resourceManagers);
}
- public Transaction getTransaction() throws SystemException {
+ public Transaction getTransaction() {
return (Transaction) threadTx.get();
}
@@ -136,7 +138,7 @@
fireThreadAssociated(tx);
}
- private void unassociate() throws SystemException {
+ private void unassociate() {
Transaction tx = getTransaction();
if (tx != null) {
associatedTransactions.remove(tx);
@@ -200,8 +202,53 @@
associate((TransactionImpl) tx);
}
- public void setRollbackOnly() throws IllegalStateException, SystemException {
- Transaction tx = getTransaction();
+ public Object getResource(Object key) {
+ TransactionImpl tx = getActiveTransactionImpl();
+ return tx.getResource(key);
+ }
+
+ private TransactionImpl getActiveTransactionImpl() {
+ TransactionImpl tx = (TransactionImpl)threadTx.get();
+ if (tx == null) {
+ throw new IllegalStateException("No tx on thread");
+ }
+ if (tx.getStatus() != Status.STATUS_ACTIVE) {
+ throw new IllegalStateException("Transaction " + tx + " is not active");
+ }
+ return tx;
+ }
+
+ public boolean getRollbackOnly() {
+ TransactionImpl tx = getActiveTransactionImpl();
+ return tx.getRollbackOnly();
+ }
+
+ public Object getTransactionKey() {
+ TransactionImpl tx = getActiveTransactionImpl();
+ return tx.getTransactionKey();
+ }
+
+ public int getTransactionStatus() {
+ TransactionImpl tx = getActiveTransactionImpl();
+ return tx.getTransactionStatus();
+ }
+
+ public void putResource(Object key, Object value) {
+ TransactionImpl tx = getActiveTransactionImpl();
+ tx.putResource(key, value);
+ }
+
+ /**
+ * jta 1.1 method so the jpa implementations can be told to flush their caches.
+ * @param synchronization
+ */
+ public void registerInterposedSynchronization(Synchronization synchronization) {
+ TransactionImpl tx = getActiveTransactionImpl();
+ tx.registerInterposedSynchronization(synchronization);
+ }
+
+ public void setRollbackOnly() throws IllegalStateException {
+ TransactionImpl tx = (TransactionImpl) threadTx.get();
if (tx == null) {
throw new IllegalStateException("No transaction associated with current thread");
}
@@ -301,7 +348,7 @@
}
protected void recoverResourceManager(ResourceManager resourceManager) {
- NamedXAResource namedXAResource = null;
+ NamedXAResource namedXAResource;
try {
namedXAResource = resourceManager.getRecoveryXAResources();
} catch (SystemException e) {