dain 2005/02/25 18:06:11
Modified: modules/core/src/java/org/openejb/mdb EndpointHandler.java
MDBInstanceContext.java MDBInstanceInterceptor.java
Log:
Added support for in-tx cacheing back in
This unturned a load of places that were not handling transaction contexts
properly and bugs in the context itself
Changed instance contexts so they track entrancy and can be killed as
required by the spec
Made all instance context fields final
Revision Changes Path
1.5 +20 -10
openejb/modules/core/src/java/org/openejb/mdb/EndpointHandler.java
Index: EndpointHandler.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/EndpointHandler.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- EndpointHandler.java 13 Oct 2004 16:44:34 -0000 1.4
+++ EndpointHandler.java 25 Feb 2005 23:06:11 -0000 1.5
@@ -53,6 +53,7 @@
import javax.ejb.EJBException;
import javax.resource.ResourceException;
import javax.transaction.xa.XAResource;
+import javax.transaction.Transaction;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
@@ -62,6 +63,7 @@
import org.apache.geronimo.transaction.context.InheritableTransactionContext;
import org.apache.geronimo.transaction.context.TransactionContext;
import org.apache.geronimo.transaction.context.TransactionContextManager;
+import org.apache.geronimo.transaction.context.ContainerTransactionContext;
import org.apache.geronimo.transaction.manager.NamedXAResource;
import org.openejb.EJBInterfaceType;
import org.openejb.EJBInvocation;
@@ -170,6 +172,14 @@
private Object invoke(int methodIndex, Object[] args) throws Throwable {
InvocationResult result;
EJBInvocation invocation = new
EJBInvocationImpl(EJBInterfaceType.LOCAL, null, methodIndex, args);
+
+ // set the transaction context
+ TransactionContext transactionContext =
TransactionContext.getContext();
+ if (transactionContext == null) {
+ throw new IllegalStateException("Transaction context has not
been set");
+ }
+ invocation.setTransactionContext(transactionContext);
+
try {
result = container.invoke(invocation);
} catch (Throwable t) {
@@ -313,7 +323,7 @@
// start a new container transaction
beanTransaction =
transactionContextManager.newContainerTransactionContext();
if (xaResource != null) {
-
beanTransaction.getTransaction().enlistResource(xaResource);
+ ((ContainerTransactionContext)
beanTransaction).getTransaction().enlistResource(xaResource);
}
} else {
// enter an unspecified transaction context
@@ -350,17 +360,17 @@
try {
//TODO is this delist necessary???????
//check we are really in a transaction.
- if (xaResource != null &&
beanTransaction.getTransaction() != null) {
-
beanTransaction.getTransaction().delistResource(xaResource,
XAResource.TMSUSPEND);
+ if (xaResource != null && beanTransaction instanceof
ContainerTransactionContext) {
+ Transaction transaction =
((ContainerTransactionContext) beanTransaction).getTransaction();
+ if (transaction != null) {
+ transaction.delistResource(xaResource,
XAResource.TMSUSPEND);
+ }
}
- beanTransaction.commit();
} catch (Throwable t) {
- try {
- beanTransaction.rollback();
- } catch (Exception e) {
- log.warn("Unable to roll back", e);
- }
+ beanTransaction.setRollbackOnly();
throw t;
+ } finally {
+ beanTransaction.commit();
}
}
} catch (Throwable t) {
1.12 +49 -12
openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceContext.java
Index: MDBInstanceContext.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceContext.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- MDBInstanceContext.java 14 Feb 2005 18:32:31 -0000 1.11
+++ MDBInstanceContext.java 25 Feb 2005 23:06:11 -0000 1.12
@@ -57,6 +57,7 @@
import org.openejb.AbstractInstanceContext;
import org.openejb.EJBOperation;
import org.openejb.EJBInvocation;
+import org.openejb.cache.InstancePool;
import org.openejb.dispatch.SystemMethodIndices;
import org.openejb.timer.BasicTimerService;
@@ -66,14 +67,15 @@
* @version $Revision$ $Date$
*/
public final class MDBInstanceContext extends AbstractInstanceContext {
- private final Object containerId;
private final MDBContext mdbContext;
+ private final EJBInvocation setContextInvocation;
+ private final EJBInvocation unsetContextInvocation;
private final EJBInvocation ejbCreateInvocation;
private final EJBInvocation ejbRemoveInvocation;
+ private InstancePool pool;
public MDBInstanceContext(Object containerId, MessageDrivenBean
instance, TransactionContextManager transactionContextManager,
UserTransactionImpl userTransaction, SystemMethodIndices systemMethodIndices,
Interceptor systemChain, Set unshareableResources, Set
applicationManagedSecurityResources, BasicTimerService timerService) {
- super(systemChain, unshareableResources,
applicationManagedSecurityResources, instance, null, timerService);
- this.containerId = containerId;
+ super(containerId, instance, systemChain, null, timerService,
unshareableResources, applicationManagedSecurityResources);
this.mdbContext = new MDBContext(this, transactionContextManager,
userTransaction);
ejbCreateInvocation =
systemMethodIndices.getEJBCreateInvocation(this);
ejbRemoveInvocation =
systemMethodIndices.getEJBRemoveInvocation(this);
@@ -81,22 +83,37 @@
unsetContextInvocation =
systemMethodIndices.getSetContextInvocation(this, null);
}
- public Object getContainerId() {
- return containerId;
- }
-
public Object getId() {
return null;
}
- public void setId(Object id) {
- throw new AssertionError("Cannot set identity for a MDB Context");
- }
-
public void flush() {
throw new AssertionError("Cannot flush a MDB Context");
}
+ public InstancePool getPool() {
+ return pool;
+ }
+
+ public void setPool(InstancePool pool) {
+ this.pool = pool;
+ }
+
+ public void die() {
+ if (pool != null) {
+ pool.remove(this);
+ pool = null;
+ }
+ super.die();
+ }
+
+ public void exit() {
+ if (pool != null) {
+ pool.release(this);
+ }
+ super.exit();
+ }
+
public MDBContext getMessageDrivenContext() {
return mdbContext;
}
@@ -109,12 +126,32 @@
return mdbContext.setTimerState(operation);
}
+ public void setContext() throws Throwable {
+ if (isDead()) {
+ throw new IllegalStateException("Context is dead: container=" +
getContainerId() + ", id=" + getId());
+ }
+ systemChain.invoke(setContextInvocation);
+ }
+
+ public void unsetContext() throws Throwable {
+ if (isDead()) {
+ throw new IllegalStateException("Context is dead: container=" +
getContainerId() + ", id=" + getId());
+ }
+ systemChain.invoke(unsetContextInvocation);
+ }
+
public void ejbCreate() throws Throwable {
+ if (isDead()) {
+ throw new IllegalStateException("Context is dead: container=" +
getContainerId() + ", id=" + getId());
+ }
assert(getInstance() != null);
systemChain.invoke(ejbCreateInvocation);
}
public void ejbRemove() throws Throwable {
+ if (isDead()) {
+ throw new IllegalStateException("Context is dead: container=" +
getContainerId() + ", id=" + getId());
+ }
assert(getInstance() != null);
systemChain.invoke(ejbRemoveInvocation);
}
1.2 +9 -7
openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceInterceptor.java
Index: MDBInstanceInterceptor.java
===================================================================
RCS file:
/home/projects/openejb/scm/openejb/modules/core/src/java/org/openejb/mdb/MDBInstanceInterceptor.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- MDBInstanceInterceptor.java 1 Mar 2004 07:14:43 -0000 1.1
+++ MDBInstanceInterceptor.java 25 Feb 2005 23:06:11 -0000 1.2
@@ -53,6 +53,7 @@
import org.apache.geronimo.core.service.Interceptor;
import org.apache.geronimo.core.service.Invocation;
import org.apache.geronimo.core.service.InvocationResult;
+import org.apache.geronimo.transaction.InstanceContext;
/**
@@ -78,22 +79,23 @@
// get the context
MDBInstanceContext ctx = (MDBInstanceContext) pool.acquire();
assert ctx.getInstance() != null: "Got a context with no instance
assigned";
+ assert !ctx.isInCall() : "Acquired a context already in an
invocation";
+ ctx.setPool(pool);
// initialize the context and set it into the invocation
ejbInvocation.setEJBInstanceContext(ctx);
+ InstanceContext oldContext =
ejbInvocation.getTransactionContext().beginInvocation(ctx);
try {
InvocationResult result = next.invoke(invocation);
-
- // we are done with this instance, return it to the pool
- pool.release(ctx);
-
return result;
} catch (Throwable t) {
- // invocation threw a system Exception, discard the instance
- pool.remove(ctx);
+ // we must kill the instance when a system exception is thrown
+ ctx.die();
throw t;
} finally {
+ ejbInvocation.getTransactionContext().endInvocation(oldContext);
+
// remove the reference to the context from the invocation
ejbInvocation.setEJBInstanceContext(null);
}