Where is BeanLockSupport?

--jason


On Thu, 2 Aug 2001, marc fleury wrote:

>   User: mnf999
>   Date: 01/08/02 19:59:04
>
>   Added:       src/main/org/jboss/ejb/plugins/lock
>                         SimplePessimisticEJBLock.java
>   Log:
>   nuff said
>
>   Revision  Changes    Path
>   1.1                  
>jboss/src/main/org/jboss/ejb/plugins/lock/SimplePessimisticEJBLock.java
>
>   Index: SimplePessimisticEJBLock.java
>   ===================================================================
>   /*
>   * JBoss, the OpenSource EJB server
>   *
>   * Distributable under LGPL license.
>   * See terms of license at gnu.org.
>   */
>
>   package org.jboss.ejb.plugins.lock;
>
>   import java.util.LinkedList;
>   import java.util.HashMap;
>   import java.util.Collections;
>   import java.lang.reflect.Method;
>
>   import javax.transaction.Transaction;
>   import javax.transaction.Status;
>   import javax.transaction.Synchronization;
>   import javax.transaction.TransactionManager;
>   import javax.transaction.RollbackException;
>   import javax.ejb.EJBObject;
>
>   import org.jboss.ejb.MethodInvocation;
>   import org.jboss.logging.log4j.JBossCategory;
>
>   /**
>    * Holds all locks for entity beans, not used for stateful. <p>
>    *
>    * All BeanLocks have a reference count.
>    * When the reference count goes to 0, the lock is released from the
>    * id -> lock mapping.
>    *
>    * @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
>    * @author <a href="[EMAIL PROTECTED]">Marc Fleury</a>
>    *
>    * @version $Revision: 1.1 $
>    *
>    * <p><b>Revisions:</b><br>
>   *  <p><b>2001/07/29: billb</b>
>   *  <ol>
>   *   <li>Initial revision
>   * </ol>
>   *  <p><b>2001/08/01: marcf</b>
>   *  <ol>
>   *   <li>Added the schedule method
>   *   <li>The bean lock is now responsible for implementing the locking policies, it 
>was before in the
>   *   interceptor code it is now factored out allowing for pluggable lock policies 
>(optimistic for ex)
>   *   <li>Implemented pessimistic locking and straight spec requirement in the 
>schedule method
>   *   would need to factor this in an abstract class for the BeanLock that extending 
>policies can use
>   * </ol>
>     <p><b>2001/08/02: marcf</b>
>   *  <ol>
>   *   <li>Did what was said above, moved to an extension based mech with an abstract 
>base class.
>   *   <li>This is the simple lock, won't scale well (imho) but is robust in normal 
>operation
>   *   <li>The class must now implement schedule and the various notification calls.  
>EndTransaction
>   *   wontSynchronize can be radically different (N-Lock)
>   * </ol>
>    */
>   public class SimplePessimisticEJBLock extends BeanLockSupport
>   {
>      /**
>       * Schedule(MethodInvocation)
>       *
>       * Schedule implements a particular policy for scheduling the threads coming in.
>       * There is always the spec required "serialization" but we can add custom 
>scheduling in here
>       *
>       * Synchronizing on lock: a failure to get scheduled must result in a wait() 
>call and a
>       * release of the lock.  Schedulation must return with lock.
>       *
>       * @return boolean returns true if the thread is scheduled to go through the 
>rest of the
>       *  interceptors.  Returns false if the interceptor must try the scheduling 
>again.
>       */
>      public boolean schedule(MethodInvocation mi)
>         throws Exception
>      {
>         this.sync();
>         boolean syncAlreadyReleased = false;
>         try
>         {
>
>            Transaction miTx = mi.getTransaction();
>            boolean trace = true;//log.isTraceEnabled();
>
>            if( trace ) log.trace("Begin schedule, key="+mi.getId());
>
>            // Maybe my transaction already expired?
>            if (miTx != null && miTx.getStatus() == Status.STATUS_MARKED_ROLLBACK)
>            {
>               log.error("Saw rolled back tx="+miTx);
>
>                               //Wake up the next ones, this won't scale, under 
>stress we will wake everyone...
>                               //synchronized(lock) {lock.notifyAll();}
>
>                               //and get out of here
>                throw new RuntimeException("Transaction marked for rollback, possibly 
>a timeout");
>            }
>
>            //Next test is independent of whether the context is locked or not, it is 
>purely transactional
>            // Is the instance involved with another transaction? if so we implement 
>pessimistic locking
>
>            // Do we have a running transaction with the context?
>            if (tx != null &&
>                // And are we trying to enter with another transaction?
>                !tx.equals(miTx))
>            {
>               // That's no good, only one transaction per context
>               // Let's put the thread to sleep the transaction demarcation will wake 
>them up
>               if( trace ) log.trace("Transactional contention on context"+id);
>
>               try
>               {
>                  if( trace ) log.trace("Begin wait on Tx="+tx);
>
>                  // And lock the threads on the lock corresponding to the Tx in MI
>                  synchronized(lock)
>                  {
>                     // We are going to wait on one of the implementation locks 
>therefore
>                     // we need to release the sync on the BeanLock object itself
>                     syncAlreadyReleased = true;
>
>                                               releaseSync();
>
>                                               //Wait a thread coming out will wake 
>you up
>                                               //lock.wait(txTimeout);
>                     lock.wait(5000);
>
>                                  }
>                  if( trace ) log.trace("End wait on TxLock="+tx);
>               }
>
>               // We need to try again
>               finally {return false;}
>            }
>
>            // The following code should really be done in a superclass of the lock
>            // it implements the default serialization from the specification
>
>            // The next test is the pure serialization from the EJB specification.
>            // If we are here we either did not have a tx(tx == null) or this is a
>            // recursive call and the current ctx.tx == mi.tx
>
>            // The transaction is good and current.
>
>            //Is the context used already (with or without a transaction), is it 
>locked?
>            if (isMethodLocked())
>            {
>               // It is locked but re-entrant calls permitted (reentrant home ones 
>are ok as well)
>               if (!isCallAllowed(mi))
>               {
>                  // This instance is in use and you are not permitted to reenter
>                  // Go to sleep and wait for the lock to be released
>                  if( trace ) log.trace("Thread contention on lock"+id);
>
>                  // Threads finishing invocation will notify() on the lock
>                  try
>                  {
>
>                     if( trace ) log.trace("Begin lock.wait(), id="+mi.getId());
>
>                                          synchronized(lock)
>                     {
>                        // we're about to wait on a different object, so release 
>synch on beanlock
>                        // Also, this notify should always be within the synch(lock) 
>block
>                        syncAlreadyReleased = true;
>                        releaseSync();
>
>                        //lock.wait(txTimeout);
>                        lock.wait(5000);
>                                               }
>                  }
>
>                  catch (InterruptedException ignored) {}
>                  // We need to try again
>                  finally
>                  {
>                     if( trace ) log.trace("End lock.wait(), id="+mi.getId()+", 
>isLocked="+isMethodLocked());
>                     return false;
>                  }
>               }
>               else
>               {
>                  //We are in a valid reentrant call so add a method lock
>                  addMethodLock();
>               }
>            }
>            // No one is using that instance
>            else
>            {
>               // We are now using the instance
>               addMethodLock();
>            }
>
>            // keep track of the transaction in the lock
>            tx = miTx;
>         }
>         finally
>         {
>            if (!syncAlreadyReleased) this.releaseSync();
>         }
>
>         //If we reach here we are properly scheduled to go through so return true
>         return true;
>      }
>
>       //This is called if the synchronization missed registration (Sync interceptor)
>       public void wontSynchronize(Transaction transaction)
>       {
>               tx = null;
>
>               synchronized(lock) {lock.notifyAll();}
>       }
>
>       // This is called up synchronization to notify the end of the transaction
>       public void endTransaction(Transaction transaction)
>       {
>          //The tx is done
>               tx = null;
>
>               synchronized(lock) {lock.notifyAll();}
>       }
>
>
>       /**
>       * releaseMethodLock
>       *
>       * if we reach the count of zero it means the instance is free from threads 
>(and reentrency)
>       * we wake up the next thread in the currentLock
>       */
>      public void releaseMethodLock()
>      {
>         numMethodLocks--;
>
>               //Wake up a thread to do work on the instance within the current 
>transaction
>         if (numMethodLocks ==0) synchronized(lock) {lock.notifyAll();}
>
>      }
>   }
>
>
>
>
> _______________________________________________
> Jboss-development mailing list
> [EMAIL PROTECTED]
> http://lists.sourceforge.net/lists/listinfo/jboss-development
>


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

Reply via email to