You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by da...@apache.org on 2007/01/11 01:33:15 UTC
svn commit: r495063 - in
/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb:
assembler/classic/JndiEncBuilder.java core/CoreUserTransaction.java
ri/sp/PseudoTransactionService.java
Author: dain
Date: Wed Jan 10 16:33:14 2007
New Revision: 495063
URL: http://svn.apache.org/viewvc?view=rev&rev=495063
Log:
OPENEJB-441 added support for TransactionSynchronizationRegistry
Modified:
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreUserTransaction.java
incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoTransactionService.java
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java?view=diff&rev=495063&r1=495062&r2=495063
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/JndiEncBuilder.java Wed Jan 10 16:33:14 2007
@@ -32,6 +32,7 @@
import javax.persistence.EntityManagerFactory;
import javax.transaction.TransactionManager;
import javax.transaction.UserTransaction;
+import javax.transaction.TransactionSynchronizationRegistry;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
@@ -134,10 +135,21 @@
public Context build() throws OpenEJBException {
Map<String, Object> bindings = new HashMap<String, Object>();
- if (beanManagedTransactions) {
- Object obj = Assembler.getContext().get(TransactionManager.class.getName());
- TransactionManager transactionManager = (TransactionManager) obj;
+ // bind TransactionManager
+ TransactionManager transactionManager = (TransactionManager) Assembler.getContext().get(TransactionManager.class.getName());
+ bindings.put("java:comp/TransactionManager", transactionManager);
+ // bind TransactionSynchronizationRegistry
+ TransactionSynchronizationRegistry synchronizationRegistry = (TransactionSynchronizationRegistry) Assembler.getContext().get(TransactionSynchronizationRegistry.class.getName());
+ if (synchronizationRegistry == null && transactionManager instanceof TransactionSynchronizationRegistry) {
+ synchronizationRegistry = (TransactionSynchronizationRegistry) transactionManager;
+ }
+ if (synchronizationRegistry != null) {
+ bindings.put("java:comp/TransactionSynchronizationRegistry", synchronizationRegistry);
+ }
+
+ // bind UserTransaction if bean managed transactions
+ if (beanManagedTransactions) {
Object userTransaction = referenceWrapper.wrap(new CoreUserTransaction(transactionManager));
bindings.put("java:comp/UserTransaction", userTransaction);
}
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreUserTransaction.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreUserTransaction.java?view=diff&rev=495063&r1=495062&r2=495063
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreUserTransaction.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/core/CoreUserTransaction.java Wed Jan 10 16:33:14 2007
@@ -40,11 +40,9 @@
}
private TransactionManager transactionManager() {
- // DMB: taking this out is fine unless it is serialized as part of a stateful sessionbean passivation
- // when the bean is activated
-// if (transactionManager == null) {
-// transactionManager = org.apache.openejb.OpenEJB.getTransactionManager();
-// }
+ if (transactionManager == null) {
+ transactionManager = org.apache.openejb.OpenEJB.getTransactionManager();
+ }
return transactionManager;
}
Modified: incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoTransactionService.java
URL: http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoTransactionService.java?view=diff&rev=495063&r1=495062&r2=495063
==============================================================================
--- incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoTransactionService.java (original)
+++ incubator/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/ri/sp/PseudoTransactionService.java Wed Jan 10 16:33:14 2007
@@ -1,152 +1,192 @@
-/**
- * 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.
- */
+/**
+ * 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.openejb.ri.sp;
-import org.apache.openejb.spi.TransactionService;
-
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import javax.transaction.InvalidTransactionException;
+import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.Status;
import javax.transaction.Synchronization;
import javax.transaction.Transaction;
import javax.transaction.TransactionManager;
-import javax.transaction.UserTransaction;
+import javax.transaction.TransactionSynchronizationRegistry;
+import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.Vector;
+
+import org.apache.openejb.spi.TransactionService;
+import org.apache.openejb.util.Logger;
/**
* @org.apache.xbean.XBean element="pseudoTransactionService"
*/
-public class PseudoTransactionService implements TransactionService, TransactionManager {
- Hashtable map = new Hashtable();
+public class PseudoTransactionService implements TransactionService, TransactionManager, TransactionSynchronizationRegistry {
+ private static final Logger logger = Logger.getInstance("OpenEJB", "org.apache.openejb.core.cmp");
+ private final ThreadLocal<MyTransaction> threadTransaction = new ThreadLocal<MyTransaction>();
- public void init(java.util.Properties props) {
+ public void init(Properties props) {
}
public TransactionManager getTransactionManager() {
return this;
}
- public UserTransaction getUserTransaction(Object txID) {
- return new UserTransaction() {
- public void begin() {
- PseudoTransactionService.this.begin();
- }
-
- public void commit() throws RollbackException {
- PseudoTransactionService.this.commit();
- }
+ public TransactionSynchronizationRegistry getTransactionSynchronizationRegistry() {
+ return this;
+ }
- public int getStatus() throws javax.transaction.SystemException {
- return PseudoTransactionService.this.getStatus();
- }
+ public int getStatus() {
+ MyTransaction tx = threadTransaction.get();
+ if (tx == null) {
+ return Status.STATUS_NO_TRANSACTION;
+ }
+ return tx.getStatus();
+ }
- public void rollback() {
- PseudoTransactionService.this.rollback();
- }
+ public Transaction getTransaction() {
+ return threadTransaction.get();
+ }
- public void setRollbackOnly() {
- PseudoTransactionService.this.setRollbackOnly();
- }
+ public boolean getRollbackOnly() {
+ MyTransaction tx = threadTransaction.get();
+ if (tx == null) {
+ throw new IllegalStateException("No transaction active");
+ }
+ return tx.getRollbackOnly();
+ }
- public void setTransactionTimeout(int seconds) {
- PseudoTransactionService.this.setTransactionTimeout(seconds);
- }
- };
+ public void setRollbackOnly() {
+ MyTransaction tx = threadTransaction.get();
+ if (tx == null) {
+ throw new IllegalStateException("No transaction active");
+ }
+ tx.setRollbackOnly();
}
- public void begin() {
- Transaction tx = new MyTransaction();
- map.put(Thread.currentThread(), tx);
+ public void begin() throws NotSupportedException {
+ if (threadTransaction.get() != null) {
+ throw new NotSupportedException("A transaction is already active");
+ }
+
+ MyTransaction tx = new MyTransaction();
+ threadTransaction.set(tx);
}
public void commit() throws RollbackException {
- MyTransaction tx = (MyTransaction) map.remove(Thread.currentThread());
- if (tx != null) {
+ MyTransaction tx = threadTransaction.get();
+ if (tx == null) {
+ throw new IllegalStateException("No transaction active");
+ }
+
+ try {
tx.commit();
- } else {
- throw new IllegalStateException();
+ } finally {
+ threadTransaction.set(null);
}
}
- public int getStatus() throws javax.transaction.SystemException {
- Transaction tx = (Transaction) map.get(Thread.currentThread());
+
+ public void rollback() {
+ MyTransaction tx = threadTransaction.get();
if (tx == null) {
- return Status.STATUS_NO_TRANSACTION;
+ throw new IllegalStateException("No transaction active");
+ }
+
+ try {
+ tx.rollback();
+ } finally {
+ threadTransaction.set(null);
}
- return tx.getStatus();
}
- public Transaction getTransaction() {
- return (Transaction) map.get(Thread.currentThread());
+ public Transaction suspend() {
+ return threadTransaction.get();
}
- public void resume(Transaction tx)
- throws javax.transaction.SystemException, javax.transaction.InvalidTransactionException {
- Transaction ctx = (Transaction) map.get(Thread.currentThread());
- int status = tx.getStatus();
+ public void resume(Transaction tx) throws InvalidTransactionException {
+ if (tx == null) {
+ throw new InvalidTransactionException("Transaction is null");
+ }
+ if (!(tx instanceof MyTransaction)) {
+ throw new InvalidTransactionException("Unknown transaction type " + tx.getClass().getName());
+ }
+ MyTransaction myTransaction = (MyTransaction) tx;
+
+ if (threadTransaction.get() != null) {
+ throw new IllegalStateException("A transaction is already active");
+ }
- if (ctx != null || tx == null || (status != Status.STATUS_ACTIVE && status != Status.STATUS_MARKED_ROLLBACK)) {
- throw new javax.transaction.InvalidTransactionException();
+ int status = myTransaction.getStatus();
+ if (status != Status.STATUS_ACTIVE && status != Status.STATUS_MARKED_ROLLBACK) {
+ throw new InvalidTransactionException("Expected transaction to be STATUS_ACTIVE or STATUS_MARKED_ROLLBACK, but was " + status);
}
- map.put(Thread.currentThread(), tx);
+
+ threadTransaction.set(myTransaction);
}
- public Transaction suspend() {
- return (Transaction) map.remove(Thread.currentThread());
+ public Object getTransactionKey() {
+ return getTransaction();
}
- public void rollback() {
- MyTransaction tx = (MyTransaction) map.remove(Thread.currentThread());
+ public int getTransactionStatus() {
+ return getStatus();
+ }
+
+ public Object getResource(Object key) {
+ MyTransaction tx = threadTransaction.get();
if (tx == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("No transaction active");
}
- tx.rollback();
+
+ Object value = tx.getResource(key);
+ return value;
}
- public void setRollbackOnly() {
- MyTransaction tx = (MyTransaction) map.get(Thread.currentThread());
+ public void putResource(Object key, Object value) {
+ MyTransaction tx = threadTransaction.get();
if (tx == null) {
- throw new IllegalStateException();
+ throw new IllegalStateException("No transaction active");
}
- tx.setRollbackOnly();
+
+ tx.putResource(key, value);
+ }
+
+ public void registerInterposedSynchronization(Synchronization synchronization) {
+ MyTransaction tx = threadTransaction.get();
+ if (tx == null) {
+ throw new IllegalStateException("No transaction active");
+ }
+
+ tx.registerInterposedSynchronization(synchronization);
}
- public void setTransactionTimeout(int x) {
+ public void setTransactionTimeout(int seconds) {
}
public class MyTransaction implements Transaction {
- Vector registeredSynchronizations = new Vector();
- Vector xaResources = new Vector();
- int status = Status.STATUS_ACTIVE;
-
- public void commit() throws RollbackException {
- if (status == Status.STATUS_MARKED_ROLLBACK) {
- rollback();
- throw new RollbackException();
- }
- doBeforeCompletion();
- doXAResources(Status.STATUS_COMMITTED);
- status = Status.STATUS_COMMITTED;
- doAfterCompletion(Status.STATUS_COMMITTED);
- registeredSynchronizations = new Vector();
- map.remove(Thread.currentThread());
- }
+ private final List<Synchronization> registeredSynchronizations = Collections.synchronizedList(new ArrayList<Synchronization>());
+ private final List<XAResource> xaResources = Collections.synchronizedList(new ArrayList<XAResource>());
+ private final Map<Object, Object> resources = new HashMap<Object,Object>();
+ private int status = Status.STATUS_ACTIVE;
public boolean delistResource(XAResource xaRes, int flag) {
xaResources.remove(xaRes);
@@ -154,7 +194,7 @@
}
public boolean enlistResource(XAResource xaRes) {
- xaResources.addElement(xaRes);
+ xaResources.add(xaRes);
return true;
}
@@ -162,79 +202,110 @@
return status;
}
- public void registerSynchronization(Synchronization sync) {
- registeredSynchronizations.addElement(sync);
+ public void registerSynchronization(Synchronization synchronization) {
+ registeredSynchronizations.add(synchronization);
}
- public void rollback() {
- doXAResources(Status.STATUS_ROLLEDBACK);
- doAfterCompletion(Status.STATUS_ROLLEDBACK);
- status = Status.STATUS_ROLLEDBACK;
- registeredSynchronizations = new Vector();
- map.remove(Thread.currentThread());
+ public void registerInterposedSynchronization(Synchronization synchronization) {
+ registeredSynchronizations.add(synchronization);
+ }
+
+ public boolean getRollbackOnly() {
+ return status == Status.STATUS_MARKED_ROLLBACK;
}
public void setRollbackOnly() {
status = Status.STATUS_MARKED_ROLLBACK;
}
+ public Object getResource(Object key) {
+ if (key == null) throw new NullPointerException("key is null");
+ return resources.get(key);
+ }
- private void doBeforeCompletion() {
- Enumeration enumeration = registeredSynchronizations.elements();
- while (enumeration.hasMoreElements()) {
+ public void putResource(Object key, Object value) {
+ if (key == null) throw new NullPointerException("key is null");
+ if (value != null) {
+ resources.put(key, value);
+ } else {
+ resources.remove(key);
+ }
+ }
+
+ public void commit() throws RollbackException {
+ try {
+ if (status == Status.STATUS_MARKED_ROLLBACK) {
+ rollback();
+ throw new RollbackException();
+ }
try {
- Synchronization sync = (Synchronization) enumeration.nextElement();
- sync.beforeCompletion();
- } catch (RuntimeException re) {
- re.printStackTrace();
+ doBeforeCompletion();
+ } catch (Exception e) {
+ rollback();
+ throw (RollbackException) new RollbackException().initCause(e);
}
+ doXAResources(Status.STATUS_COMMITTED);
+ status = Status.STATUS_COMMITTED;
+ doAfterCompletion(Status.STATUS_COMMITTED);
+ } finally {
+ threadTransaction.set(null);
+ }
+ }
+
+ public void rollback() {
+ try {
+ doXAResources(Status.STATUS_ROLLEDBACK);
+ doAfterCompletion(Status.STATUS_ROLLEDBACK);
+ status = Status.STATUS_ROLLEDBACK;
+ registeredSynchronizations.clear();
+ } finally {
+ threadTransaction.set(null);
+ }
+ }
+
+ private void doBeforeCompletion() {
+ for (Synchronization sync : new ArrayList<Synchronization>(registeredSynchronizations)) {
+ sync.beforeCompletion();
}
}
private void doAfterCompletion(int status) {
- Enumeration enumeration = registeredSynchronizations.elements();
- while (enumeration.hasMoreElements()) {
+ for (Synchronization sync : new ArrayList<Synchronization>(registeredSynchronizations)) {
try {
- Synchronization sync = (Synchronization) enumeration.nextElement();
sync.afterCompletion(status);
- } catch (RuntimeException re) {
- re.printStackTrace();
+ } catch (RuntimeException e) {
+ logger.warning("Synchronization afterCompletion threw a RuntimeException", e);
}
}
}
private void doXAResources(int status) {
- Object [] resources = xaResources.toArray();
- for (int i = 0; i < resources.length; i++) {
- XAResource xaRes = (XAResource) resources[i];
+ for (XAResource xaRes : new ArrayList<XAResource>(xaResources)) {
if (status == Status.STATUS_COMMITTED) {
try {
xaRes.commit(null, true);
- } catch (javax.transaction.xa.XAException xae) {
+ } catch (XAException e) {
}
try {
xaRes.end(null, XAResource.TMSUCCESS);
- } catch (javax.transaction.xa.XAException xae) {
+ } catch (XAException e) {
}
} else {
try {
xaRes.rollback(null);
- } catch (javax.transaction.xa.XAException xae) {
+ } catch (XAException e) {
}
try {
xaRes.end(null, XAResource.TMFAIL);
- } catch (javax.transaction.xa.XAException xae) {
-
+ } catch (XAException e) {
}
}
}
- xaResources = new Vector();
-
+ xaResources.clear();
}
-
}
}