User: mnf999  
  Date: 01/08/01 11:48:06

  Modified:    src/main/org/jboss/ejb/plugins
                        StatefulSessionInstanceInterceptor.java
  Log:
  Bill's Stateful int with externalized bean this could be moved to a full interceptor 
like the entity
  
  Revision  Changes    Path
  1.20      +140 -94   
jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java
  
  Index: StatefulSessionInstanceInterceptor.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jboss/src/main/org/jboss/ejb/plugins/StatefulSessionInstanceInterceptor.java,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- StatefulSessionInstanceInterceptor.java   2001/07/20 20:07:15     1.19
  +++ StatefulSessionInstanceInterceptor.java   2001/08/01 18:48:06     1.20
  @@ -20,6 +20,8 @@
   
   import org.apache.log4j.Category;
   
  +import org.jboss.ejb.BeanLock;
  +import org.jboss.ejb.BeanLockManager;
   import org.jboss.ejb.Container;
   import org.jboss.ejb.InstanceCache;
   import org.jboss.ejb.InstancePool;
  @@ -28,20 +30,24 @@
   import org.jboss.ejb.EnterpriseContext;
   import org.jboss.ejb.MethodInvocation;
   import org.jboss.metadata.SessionMetaData;
  -import org.jboss.util.Sync;
   
   /**
    * This container acquires the given instance. 
    *
    * @author <a href="mailto:[EMAIL PROTECTED]";>Rickard �berg</a>
    * @author <a href="mailto:[EMAIL PROTECTED]";>Marc Fleury</a>
  - * @version $Revision: 1.19 $
  + * @author <a href="mailto:[EMAIL PROTECTED]";>Bill Burke</a>
  + * @version $Revision: 1.20 $
    *
    * <p><b>Revisions:</b>
    * <p><b>20010704 marcf</b>
    * <ul>
    * <li>- Moved to new synchronization
    * </ul>
  + * <p><b>20010726 billb</b>
  + * <ul>
  + * <li>- externalized bean locking in separate object BeanLock
  + * </ul>
    */
   public class StatefulSessionInstanceInterceptor
      extends AbstractInterceptor
  @@ -131,10 +137,10 @@
         }
      }
        
  -   private void register(EnterpriseContext ctx, Transaction tx)
  +   private void register(EnterpriseContext ctx, Transaction tx, BeanLock lock)
      {
         // Create a new synchronization
  -      InstanceSynchronization synch = new InstanceSynchronization(tx, ctx);
  +      InstanceSynchronization synch = new InstanceSynchronization(tx, ctx, lock);
                
         try {
            // OSH: An extra check to avoid warning.
  @@ -146,7 +152,17 @@
            }
                        
            // We want to be notified when the transaction commits
  -         tx.registerSynchronization(synch);
  +         try
  +         {
  +            tx.registerSynchronization(synch);
  +         }
  +         catch (Exception ex)
  +         {
  +            // synch adds a reference to the lock, so we must release the ref
  +            // because afterCompletion will never get called.
  +            getContainer().getLockManager().removeLockRef(lock.getId());
  +            throw ex;
  +         }
                        
            // EJB 1.1, 6.5.3
            synch.afterBegin();
  @@ -167,97 +183,115 @@
            (AbstractInstanceCache)container.getInstanceCache();
         Object id = mi.getId();
         EnterpriseContext ctx = null;
  -             
  -      // Get context
  -      ctx = container.getInstanceCache().get(mi.getId());
                
  -      synchronized(ctx) 
  +      BeanLock lock = (BeanLock)container.getLockManager().getLock(id);
  +      try
         {
  -                     
  -         // Associate it with the method invocation
  -         mi.setEnterpriseContext(ctx);
  -                     
  -         // BMT beans will lock and replace tx no matter what, CMT do work on 
transaction
  -         if (!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
  +         lock.sync(); // synchronized(ctx)
  +         try // lock.sync
  +         {
  +            // Get context
  +            ctx = container.getInstanceCache().get(mi.getId());
  +            // Associate it with the method invocation
  +            mi.setEnterpriseContext(ctx);
  +
  +            // BMT beans will lock and replace tx no matter what, CMT do work on 
transaction
  +            if (!((SessionMetaData)container.getBeanMetaData()).isBeanManagedTx()) {
                                
  -            // Do we have a running transaction with the context
  -            if (ctx.getTransaction() != null &&
  -                // And are we trying to enter with another transaction
  -                !ctx.getTransaction().equals(mi.getTransaction()))
  -            {
  -               // Calls must be in the same transaction
  -               throw new RemoteException("Application Error: tried to enter 
Stateful bean with different transaction context");
  -            }
  +               // Do we have a running transaction with the context
  +               if (ctx.getTransaction() != null &&
  +                   // And are we trying to enter with another transaction
  +                   !ctx.getTransaction().equals(mi.getTransaction()))
  +               {
  +                  // Calls must be in the same transaction
  +                  throw new RemoteException("Application Error: tried to enter 
Stateful bean with different transaction context");
  +               }
                                
  -            //If the instance will participate in a new transaction we register a 
sync for it
  -            if (ctx.getTransaction() == null && mi.getTransaction() != null) {
  -               register(ctx, mi.getTransaction());
  +               //If the instance will participate in a new transaction we register 
a sync for it
  +               if (ctx.getTransaction() == null && mi.getTransaction() != null) {
  +                  register(ctx, mi.getTransaction(), lock);
  +               }
               }
  -         }
                        
  -         if (!ctx.isLocked()){
  -                             
  -            //take it!
  -            ctx.lock();  
  -         } else 
  -         {
  -            if (!isCallAllowed(mi))
  +            if (!ctx.isLocked())
               {
  -               // Calls must be in the same transaction
  -               throw new RemoteException("Application Error: no concurrent calls on 
stateful beans");
  -            }
  +                             
  +               //take it!
  +               ctx.lock();  
  +            } 
               else 
               {
  -               ctx.lock();
  +               if (!isCallAllowed(mi))
  +               {
  +                  // Concurent calls are not allowed
  +                  throw new RemoteException("Application Error: no concurrent calls 
on stateful beans");
  +               }
  +               else 
  +               {
  +                  ctx.lock();
  +               }
               }
            }
  -      }
  +         finally
  +         {
  +            lock.releaseSync();
  +         }
                
  -      try
  -      {
  -         // Invoke through interceptors
  -         return getNext().invoke(mi);
  -      } catch (RemoteException e)
  -      {
  -         // Discard instance
  -         container.getInstanceCache().remove(mi.getId());
  -         ctx = null;
  +         try
  +         {
  +            // Invoke through interceptors
  +            return getNext().invoke(mi);
  +         } catch (RemoteException e)
  +         {
  +            // Discard instance
  +            container.getInstanceCache().remove(mi.getId());
  +            ctx = null;
                        
  -         throw e;
  -      } catch (RuntimeException e)
  -      {
  -         // Discard instance
  -         container.getInstanceCache().remove(mi.getId());
  -         ctx = null;
  +            throw e;
  +         } catch (RuntimeException e)
  +         {
  +            // Discard instance
  +            container.getInstanceCache().remove(mi.getId());
  +            ctx = null;
                        
  -         throw e;
  -      } catch (Error e)
  -      {
  -         // Discard instance
  -         container.getInstanceCache().remove(mi.getId());
  -         ctx = null;
  +            throw e;
  +         } catch (Error e)
  +         {
  +            // Discard instance
  +            container.getInstanceCache().remove(mi.getId());
  +            ctx = null;
                        
  -         throw e;
  -      } finally 
  -      {
  -         if (ctx != null)
  +            throw e;
  +         } finally 
            {
  -            // Still a valid instance
  -            synchronized(ctx) 
  +            if (ctx != null)
               {
  +               // Still a valid instance
  +               lock.sync(); // synchronized(ctx) 
  +               try
  +               {
                                        
  -               // release it
  -               ctx.unlock();
  +                  // release it
  +                  ctx.unlock();
                                        
  -               // if removed, remove from cache
  -               if (ctx.getId() == null)
  +                  // if removed, remove from cache
  +                  if (ctx.getId() == null)
  +                  {
  +                     // Remove from cache
  +                     container.getInstanceCache().remove(mi.getId());
  +                  }
  +               }
  +               finally
                  {
  -                  // Remove from cache
  -                  container.getInstanceCache().remove(mi.getId());
  +                  lock.releaseSync();
                  }
               }
            }
         }
  +      finally
  +      {
  +         container.getLockManager().removeLockRef(lock.getId());
  +      }
      }
        
      private boolean isCallAllowed(MethodInvocation mi) 
  @@ -296,14 +330,17 @@
         private Method afterBegin;
         private Method beforeCompletion;
         private Method afterCompletion;
  +      private BeanLock lock;
                
         /**
          *  Create a new instance synchronization instance.
          */
  -      InstanceSynchronization(Transaction tx, EnterpriseContext ctx)
  +      InstanceSynchronization(Transaction tx, EnterpriseContext ctx, BeanLock lock)
         {
            this.tx = tx;
            this.ctx = ctx;
  +         this.lock = lock;
  +         this.lock.addRef();
                        
            // Let's compute it now, to speed things up we could 
            notifySession = (ctx.getInstance() instanceof 
javax.ejb.SessionSynchronization);
  @@ -363,29 +400,38 @@
         {
            // DEBUG log.debug("afterCompletion called");
                        
  -         // finish the transaction association
  -         ctx.setTransaction(null);
  -                     
  -         // unlock this context
  -         ctx.unlock();
  -                     
  -         if (notifySession) {
  -                             
  -            try {
  -                                     
  -               if (status == Status.STATUS_COMMITTED) {
  -                  afterCompletion.invoke(ctx.getInstance(),
  -                                         new Object[] { Boolean.TRUE });
  +         lock.sync();
  +         try
  +         {
  +            // finish the transaction association
  +            ctx.setTransaction(null);
  +            
  +            // unlock this context
  +            ctx.unlock();
  +            
  +            if (notifySession) {
  +               
  +               try {
  +                  
  +                  if (status == Status.STATUS_COMMITTED) {
  +                     afterCompletion.invoke(ctx.getInstance(),
  +                                            new Object[] { Boolean.TRUE });
  +                  }
  +                  else {
  +                     afterCompletion.invoke(ctx.getInstance(),
  +                                            new Object[] { Boolean.FALSE });
  +                  }
                  }
  -               else {
  -                  afterCompletion.invoke(ctx.getInstance(),
  -                                         new Object[] { Boolean.FALSE });
  +               catch (Exception e) {
  +                  log.error("failed to invoke afterCompletion", e);
                  }
  -            }
  -            catch (Exception e) {
  -               log.error("failed to invoke afterCompletion", e);
  -            }
  -         }                   
  +            }                        
  +         }
  +         finally
  +         {
  +            lock.releaseSync();
  +            container.getLockManager().removeLockRef(lock.getId());
  +         }
         }
      }
   }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to