User: d_jencks
  Date: 02/02/12 18:35:08

  Modified:    src/main/org/jboss/ejb EntityContainer.java
                        GlobalTxEntityMap.java TxEntityMap.java
  Log:
  Made GlobalTxEntityMap only contain read-write dirty entities, to avoid calling 
ejbStore unnecessarily. Moved beforeCompletion sync code to GlobalTxEntityMap. Fix to 
bug 512826. Involves EntityContainer, GlobalTxEntityMap, TxEntityMap, 
plugins/EntitySynchronizationInterceptor, and 
plugins/cmp/jdbc/JDBCRemoveEntityCommand.java
  
  Revision  Changes    Path
  1.66      +11 -25    jboss/src/main/org/jboss/ejb/EntityContainer.java
  
  Index: EntityContainer.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/EntityContainer.java,v
  retrieving revision 1.65
  retrieving revision 1.66
  diff -u -r1.65 -r1.66
  --- EntityContainer.java      9 Feb 2002 16:09:22 -0000       1.65
  +++ EntityContainer.java      13 Feb 2002 02:35:08 -0000      1.66
  @@ -39,6 +39,7 @@
   import javax.ejb.RemoveException;
   import javax.management.j2ee.CountStatistic;
   import javax.transaction.Transaction;
  +import javax.transaction.TransactionRolledbackException;
   
   import org.jboss.deployment.DeploymentException;
   import org.jboss.invocation.Invocation;
  @@ -61,7 +62,7 @@
   * @author <a href="mailto:[EMAIL PROTECTED]";>Daniel OConnor</a>
   * @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
   * @author <a href="mailto:[EMAIL PROTECTED]";>Andreas Schaefer</a>
  -* @version $Revision: 1.65 $
  +* @version $Revision: 1.66 $
   *
   * <p><b>Revisions:</b>
   *
  @@ -157,37 +158,22 @@
      * @throws Exception if an problem occures while storing the entities
      */
      public static void synchronizeEntitiesWithinTransaction(Transaction tx)
  +      throws TransactionRolledbackException
      {
         // If there is no transaction, there is nothing to synchronize.
  -      try
  +      if(tx != null)
         {
  -         if(tx != null)
  -         {
  -            EntityEnterpriseContext[] entities = globalTxEntityMap.getEntities(tx);
  -            for (int i = 0; i < entities.length; i++)
  -            {
  -               EntityEnterpriseContext ctx = entities[i];
  -               doStore(ctx);
  -            }
  -         }
  -      }
  -      catch (Exception ex)
  -      {
  -         throw new EJBException(ex);
  +      getGlobalTxEntityMap().syncEntities(tx);
         }
      }
  +   // Public --------------------------------------------------------
      
  -   public static void doStore(EntityEnterpriseContext ctx) throws Exception
  +   public boolean isReadOnly()
      {
  -      EntityContainer container = (EntityContainer)ctx.getContainer();
  -      if (!((EntityMetaData)container.getBeanMetaData()).isReadOnly())
  -      {
  -         container.storeEntity(ctx);
  -      }
  +      return readOnly;
      }
  -   
  -   // Public --------------------------------------------------------
  -   
  +
  +
      public void setContainerInvoker(ContainerInvoker ci)
      {
         if (ci == null)
  @@ -349,7 +335,7 @@
            in.create();
            in = in.getNext();
         }
  -      
  +      readOnly = ((EntityMetaData)metaData).isReadOnly();
         // Reset classloader
         Thread.currentThread().setContextClassLoader(oldCl);
      }
  
  
  
  1.2       +93 -20    jboss/src/main/org/jboss/ejb/GlobalTxEntityMap.java
  
  Index: GlobalTxEntityMap.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/GlobalTxEntityMap.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- GlobalTxEntityMap.java    7 Aug 2001 18:06:42 -0000       1.1
  +++ GlobalTxEntityMap.java    13 Feb 2002 02:35:08 -0000      1.2
  @@ -12,7 +12,11 @@
   import javax.transaction.RollbackException;
   import javax.transaction.SystemException;
   import javax.transaction.Synchronization;
  -
  +import java.util.Iterator;
  +import java.util.Collection;
  +import org.jboss.logging.Logger;
  +import java.util.Map;
  +import javax.transaction.TransactionRolledbackException;
   
   /**
    * This class provides a way to find out what entities are contained in
  @@ -24,11 +28,14 @@
    * Entities are stored in an ArrayList to ensure specific ordering. 
    *
    * @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
  - * @version $Revision: 1.1 $
  + * @version $Revision: 1.2 $
    */
   public class GlobalTxEntityMap
   {
  -   protected HashMap m_map = new HashMap();
  +
  +   private final Logger log = Logger.getLogger(getClass());
  +
  +   protected final Map m_map = new HashMap();
       
      /**
       * associate entity with transaction
  @@ -44,25 +51,87 @@
            m_map.put(tx, entityList);
            tx.registerSynchronization(new GlobalTxEntityMapCleanup(this, tx));
         }
  -      entityList.add(entity);
  +      if (!entityList.contains(entity))
  +      {
  +      entityList.add(entity);
  +      }
      }
   
      /**
  -    * get all EntityEnterpriseContext that are involved with a transaction.
  +    * sync all EntityEnterpriseContext that are involved (and changed)
  +    * within a transaction.
       */
  -   public synchronized EntityEnterpriseContext[] getEntities(Transaction tx)
  +   public void syncEntities(Transaction tx) 
  +      throws TransactionRolledbackException
      {
  -      ArrayList entityList = (ArrayList)m_map.get(tx);
  -      if (entityList == null) // there are no entities associated
  +      Collection entities = null;
  +      synchronized (m_map)
         {
  -         return new EntityEnterpriseContext[0];
  +      entities = (Collection)m_map.remove(tx);
  +      }
  +      if (entities != null) // there are entities associated
  +      {
  +      // This is an independent point of entry. We need to make sure the
  +      // thread is associated with the right context class loader
  +      ClassLoader oldCl = Thread.currentThread().getContextClassLoader();
  +    
  +      try
  +         {
  +         EntityEnterpriseContext ctx = null;
  +         try
  +         {
  +            for (Iterator i = entities.iterator(); i.hasNext(); )
  +            {
  +               //read-only will never get into this list.
  +               ctx = (EntityEnterpriseContext)i.next();
  +               EntityContainer container = (EntityContainer)ctx.getContainer();
  +               
Thread.currentThread().setContextClassLoader(container.getClassLoader());
  +               container.storeEntity(ctx);
  +            }
  +         }
  +         catch (Exception e)
  +         {
  +            /*ejb 1.1 section 12.3.2
  +             *ejb 2 section 18.3.3
  +             *exception during store must log exception,
  +             * mark tx for rollback and throw 
  +             * a TransactionRolledBack[Local]Exception
  +             */
  +
  +            //however we may need to ignore a NoSuchEntityException -- TODO
  +            log.error("Store failed on entity: " + ctx.getId(), e);
  +            try
  +            {
  +               tx.setRollbackOnly();
  +            }
  +            catch(SystemException se)
  +            {
  +               log.warn("SystemException while trying to rollback tx: " + tx, se);
  +            }
  +            catch (IllegalStateException ise)
  +            {
  +               log.warn("IllegalStateException while trying to rollback tx: " + tx, 
ise);
  +            }
  +            finally
  +            {
  +               //How do we distinguish local/remote??
  +               throw new TransactionRolledbackException("Exception in store of 
entity :" + ctx.id);
  +            }
  +         }
  +      }
  +      finally
  +         {
  +         Thread.currentThread().setContextClassLoader(oldCl);
  +      }
  +
         }
  -      return (EntityEnterpriseContext[])
  -         entityList.toArray(new EntityEnterpriseContext[entityList.size()]);
      }
   
  +
  +
  +
      /**
  -    * Cleanup tx/entity map on tx commit/rollback
  +    * Store changed entities to resource manager in this Synchronization
       */
      private class GlobalTxEntityMapCleanup implements Synchronization
      {
  @@ -81,18 +150,22 @@
         public void beforeCompletion()
         {
            // complete
  +         boolean trace = log.isTraceEnabled();
  +         if( trace )
  +            log.trace("beforeCompletion called for tx " + tx);
  +      try
  +      {
  +         syncEntities(tx);
  +      }
  +      catch (Exception e)
  +      {//ignore - we can't throw any exceptions, it is already logged
  +      }
  +
         }
     
         public void afterCompletion(int status)
         {
  -         synchronized(map)
  -         {
  -            ArrayList entityList = (ArrayList)m_map.remove(tx);
  -            if (entityList != null)
  -            {
  -               entityList.clear();
  -            }
  -         }
  +      //no-op
         }
      }
      
  
  
  
  1.8       +3 -3      jboss/src/main/org/jboss/ejb/TxEntityMap.java
  
  Index: TxEntityMap.java
  ===================================================================
  RCS file: /cvsroot/jboss/jboss/src/main/org/jboss/ejb/TxEntityMap.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- TxEntityMap.java  9 Aug 2001 20:25:24 -0000       1.7
  +++ TxEntityMap.java  13 Feb 2002 02:35:08 -0000      1.8
  @@ -15,12 +15,12 @@
   /**
    * This class provides a way to find out what entities of a certain type that are 
contained in
    * within a transaction.  It is attached to a specific instance of a container.
  - * This class interfaces with the static GlobalTxEntityMap.  
EntitySynchronizationInterceptor
  + *<no longer - global only holds possibly dirty> This class interfaces with the 
static GlobalTxEntityMap.  EntitySynchronizationInterceptor
    * registers tx/entity pairs through this class.
    * Used in EntitySynchronizationInterceptor.
    * 
    * @author <a href="[EMAIL PROTECTED]">Bill Burke</a>
  - * @version $Revision: 1.7 $
  + * @version $Revision: 1.8 $
    *
    * Revisions:
    *
  @@ -48,7 +48,7 @@
            m_map.put(tx, entityMap);
            tx.registerSynchronization(new TxEntityMapCleanup(this, tx));
         }
  -      EntityContainer.getGlobalTxEntityMap().associate(tx, entity);
  +      //EntityContainer.getGlobalTxEntityMap().associate(tx, entity);
         entityMap.put(entity.getCacheKey(), entity);
      }
   
  
  
  

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

Reply via email to