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);
           }
  
  
  

Reply via email to