[jboss-cvs] JBossCache/src/org/jboss/cache/interceptors ...

Manik Surtani msurtani at jboss.com
Wed Sep 6 13:58:20 EDT 2006


  User: msurtani
  Date: 06/09/06 13:58:20

  Modified:    src/org/jboss/cache/interceptors   
                        InvocationContextInterceptor.java
                        TxInterceptor.java
  Added:       src/org/jboss/cache/interceptors   
                        BaseTransactionalContextInterceptor.java
  Log:
  Refactored tx interceptor so the invocation context interceptor sets up the context initially.  Also fixed some breakage in PojoTreeCache
  
  Revision  Changes    Path
  1.3       +92 -3     JBossCache/src/org/jboss/cache/interceptors/InvocationContextInterceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: InvocationContextInterceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/InvocationContextInterceptor.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -b -r1.2 -r1.3
  --- InvocationContextInterceptor.java	5 Sep 2006 18:09:56 -0000	1.2
  +++ InvocationContextInterceptor.java	6 Sep 2006 17:58:20 -0000	1.3
  @@ -6,20 +6,50 @@
    */
   package org.jboss.cache.interceptors;
   
  +import org.jboss.cache.GlobalTransaction;
  +import org.jboss.cache.InvocationContext;
  +import org.jboss.cache.config.Option;
   import org.jboss.cache.marshall.MethodCall;
  +import org.jboss.cache.marshall.MethodDeclarations;
  +
  +import javax.transaction.SystemException;
  +import javax.transaction.Transaction;
   
   /**
    * Always place this interceptor at the start of the interceptor chain to ensure invocation contexts and set up and cleaned up correctly.
    *
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
    */
  -public class InvocationContextInterceptor extends Interceptor implements InvocationContextInterceptorMBean
  +public class InvocationContextInterceptor extends BaseTransactionalContextInterceptor implements InvocationContextInterceptorMBean
   {
      public Object invoke(MethodCall call) throws Throwable
      {
  +      InvocationContext ctx = cache.getInvocationContext();
  +      Option optionOverride = ctx.getOptionOverrides();
  +      Transaction suspendedTransaction = null;
  +      boolean resumeSuspended = false;
  +
         try
         {
  -         if (cache.getInvocationContext().getOptionOverrides().isBypassInterceptorChain())
  +         setTransactionalContext(getTransaction(), getGlobalTransaction(call));
  +
  +         if (optionOverride != null && optionOverride.isFailSilently())
  +         {
  +            log.debug("FAIL_SILENTLY Option is present - suspending any ongoing transaction.");
  +            if (ctx.getTransaction() != null)
  +            {
  +               suspendedTransaction = txManager.suspend();
  +               if (log.isTraceEnabled()) log.trace("Suspending transaction " + suspendedTransaction);
  +               resumeSuspended = true;
  +            }
  +            else
  +            {
  +               log.trace("No ongoing transaction to suspend");
  +            }
  +         }
  +
  +
  +         if (optionOverride.isBypassInterceptorChain())
            {
               return getLast().invoke(call);
            }
  @@ -31,7 +61,66 @@
         finally
         {
            // clean up any invocation-scope options set up
  -         cache.getInvocationContext().getOptionOverrides().reset();
  +         optionOverride.reset();
  +
  +         if (resumeSuspended)
  +         {
  +            txManager.resume(suspendedTransaction);
         }
  +         else
  +         {
  +            if (ctx.getTransaction() != null && isValid(ctx.getTransaction()))
  +            {
  +               copyInvocationScopeOptionsToTxScope(ctx);
  +            }
  +         }
  +      }
  +   }
  +
  +   private GlobalTransaction getGlobalTransaction(MethodCall call)
  +   {
  +      GlobalTransaction gtx = null;
  +      if (MethodDeclarations.isTransactionLifecycleMethod(call.getMethodId()))
  +      {
  +         gtx = findGlobalTransaction(call.getArgs());
  +         gtx.setRemote(isRemoteGlobalTx(gtx));
  +      }
  +      return gtx;
  +   }
  +
  +   private Transaction getTransaction() throws SystemException
  +   {
  +      // this creates a context if one did not exist.
  +      if (txManager == null)
  +      {
  +         log.trace("no transaction manager configured, setting tx as null.");
  +         return null;
  +      }
  +      else
  +      {
  +         return txManager.getTransaction();
  +      }
  +   }
  +
  +   protected GlobalTransaction findGlobalTransaction(Object[] params)
  +   {
  +      int clue = 0;
  +
  +      if (params[clue] instanceof GlobalTransaction)
  +         return (GlobalTransaction) params[clue];
  +      else
  +         for (Object param : params) if (param instanceof GlobalTransaction) return (GlobalTransaction) param;
  +      return null;
  +   }
  +
  +   /**
  +    * Tests if a global transaction originated from a different cache in the cluster
  +    *
  +    * @param gtx
  +    * @return true if the gtx is remote, false if it originated locally.
  +    */
  +   private boolean isRemoteGlobalTx(GlobalTransaction gtx)
  +   {
  +      return gtx != null && (gtx.getAddress() != null) && (!gtx.getAddress().equals(cache.getLocalAddress()));
      }
   }
  
  
  
  1.60      +19 -110   JBossCache/src/org/jboss/cache/interceptors/TxInterceptor.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: TxInterceptor.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/interceptors/TxInterceptor.java,v
  retrieving revision 1.59
  retrieving revision 1.60
  diff -u -b -r1.59 -r1.60
  --- TxInterceptor.java	5 Sep 2006 18:09:56 -0000	1.59
  +++ TxInterceptor.java	6 Sep 2006 17:58:20 -0000	1.60
  @@ -14,7 +14,6 @@
   import org.jboss.cache.OptimisticTransactionEntry;
   import org.jboss.cache.ReplicationException;
   import org.jboss.cache.TransactionEntry;
  -import org.jboss.cache.TransactionTable;
   import org.jboss.cache.TreeCacheProxyImpl;
   import org.jboss.cache.config.Configuration;
   import org.jboss.cache.config.Option;
  @@ -27,9 +26,7 @@
   import javax.transaction.Synchronization;
   import javax.transaction.SystemException;
   import javax.transaction.Transaction;
  -import javax.transaction.TransactionManager;
   import java.util.HashMap;
  -import java.util.Iterator;
   import java.util.List;
   import java.util.Map;
   
  @@ -42,7 +39,7 @@
    * @author <a href="mailto:manik at jboss.org">Manik Surtani (manik at jboss.org)</a>
    * @author <a href="mailto:stevew at jofti.com">Steve Woodcock (stevew at jofti.com)</a>
    */
  -public class TxInterceptor extends Interceptor implements TxInterceptorMBean
  +public class TxInterceptor extends BaseTransactionalContextInterceptor implements TxInterceptorMBean
   {
      /**
       * List <Transaction>that we have registered for
  @@ -53,9 +50,6 @@
      private long m_commits = 0;
      private long m_rollbacks = 0;
      final static Object NULL = new Object();
  -   protected TransactionManager txManager = null;
  -   protected TransactionTable txTable = null;
  -
   
      /**
       * Set<GlobalTransaction> of GlobalTransactions that originated somewhere else (we didn't create them).
  @@ -64,14 +58,6 @@
       */
      private Map remoteTransactions = new ConcurrentHashMap();
   
  -
  -   public void setCache(CacheSPI cache)
  -   {
  -      super.setCache(cache);
  -      txManager = cache.getTransactionManager();
  -      txTable = cache.getTransactionTable();
  -   }
  -
      public Object invoke(MethodCall m) throws Throwable
      {
         if (log.isTraceEnabled())
  @@ -83,22 +69,8 @@
   
         InvocationContext ctx = cache.getInvocationContext();
   
  -      final Transaction suspendedTransaction;
         boolean scrubTxsOnExit = false;
  -      final boolean resumeSuspended;
         Option optionOverride = ctx.getOptionOverrides();
  -      ctx.setTransaction(txManager == null ? null : txManager.getTransaction());
  -
  -      if (optionOverride != null && optionOverride.isFailSilently() && ctx.getTransaction() != null)
  -      {
  -         suspendedTransaction = txManager.suspend();
  -         resumeSuspended = true;
  -      }
  -      else
  -      {
  -         suspendedTransaction = null;
  -         resumeSuspended = false;
  -      }
   
         Object result = null;
   
  @@ -111,13 +83,8 @@
            if (MethodDeclarations.isTransactionLifecycleMethod(m.getMethodId()))
            {
               // this is a prepare, commit, or rollback.
  -            // start by setting transactional details into InvocationContext.
  -            ctx.setGlobalTransaction(findGlobalTransaction(m.getArgs()));
  -
  -            if (log.isDebugEnabled()) log.debug("Got gtx from method call " + ctx.getGlobalTransaction());
  -            ctx.getGlobalTransaction().setRemote(isRemoteGlobalTx(ctx.getGlobalTransaction()));
  +            if (log.isDebugEnabled()) log.debug("Got gtx from invocation context " + ctx.getGlobalTransaction());
   
  -            //replaceGtx(m, gtxFromMethodCall);
               if (ctx.getGlobalTransaction().isRemote()) remoteTransactions.put(ctx.getGlobalTransaction(), NULL);
   
               switch (m.getMethodId())
  @@ -165,23 +132,14 @@
         }
         finally
         {
  -         if (resumeSuspended)
  -         {
  -            txManager.resume(suspendedTransaction);
  -         }
  -         else
  -         {
  -            if (ctx.getTransaction() != null && isValid(ctx.getTransaction()))
  -            {
  -               copyInvocationScopeOptionsToTxScope(ctx);
  -            }
  -         }
  -
            // we should scrub txs after every call to prevent race conditions
            // basically any other call coming in on the same thread and hijacking any running tx's
            // was highlighted in JBCACHE-606
  -         scrubInvocationCtx(scrubTxsOnExit);
   
  +         if (scrubTxsOnExit)
  +         {
  +            setTransactionalContext(null, null);
  +         }
         }
         return result;
      }
  @@ -217,33 +175,9 @@
         return retval;
      }
   
  -   protected GlobalTransaction findGlobalTransaction(Object[] params)
  -   {
  -      int clue = 0;
  -
  -      if (params[clue] instanceof GlobalTransaction)
  -         return (GlobalTransaction) params[clue];
  -      else
  -         for (Object param : params) if (param instanceof GlobalTransaction) return (GlobalTransaction) param;
  -      return null;
  -   }
  -
  -
  -   private void copyInvocationScopeOptionsToTxScope(InvocationContext ctx)
  -   {
  -      // notify the transaction entry that this override is in place.
  -      TransactionEntry entry = txTable.get(ctx.getGlobalTransaction());
  -      if (entry != null)
  -      {
  -         Option txScopeOption = new Option();
  -         txScopeOption.setCacheModeLocal(ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isCacheModeLocal());
  -         entry.setOption(txScopeOption);
  -      }
  -   }
  -
      private Object handleRemotePrepare(MethodCall m, GlobalTransaction gtx) throws Throwable
      {
  -      List modifications = (List) m.getArgs()[1];
  +      List<MethodCall> modifications = (List<MethodCall>) m.getArgs()[1];
         boolean onePhase = (Boolean) m.getArgs()[configuration.isNodeLockingOptimistic() ? 4 : 3];
   
         // Is there a local transaction associated with GTX ?
  @@ -413,7 +347,7 @@
       * @return
       * @throws Throwable
       */
  -   private Object handleOptimisticPrepare(MethodCall m, GlobalTransaction gtx, List modifications, boolean onePhase, Transaction ltx) throws Throwable
  +   private Object handleOptimisticPrepare(MethodCall m, GlobalTransaction gtx, List<MethodCall> modifications, boolean onePhase, Transaction ltx) throws Throwable
      {
         // TODO: Manik: Refactor this to pass across entire workspace?
         Object retval;
  @@ -430,7 +364,7 @@
         return retval;
      }
   
  -   private Object handlePessimisticPrepare(MethodCall m, GlobalTransaction gtx, List modifications, boolean commit, Transaction ltx) throws Exception
  +   private Object handlePessimisticPrepare(MethodCall m, GlobalTransaction gtx, List<MethodCall> modifications, boolean commit, Transaction ltx) throws Exception
      {
         boolean success = true;
         Object retval;
  @@ -512,18 +446,17 @@
         return null;
      }
   
  -   private Object replayModifications(List modifications, Transaction tx)
  +   private Object replayModifications(List<MethodCall> modifications, Transaction tx)
      {
         Object retval = null;
   
         if (modifications != null)
         {
  -         for (Iterator it = modifications.iterator(); it.hasNext();)
  +         for (MethodCall modification : modifications)
            {
  -            MethodCall method_call = (MethodCall) it.next();
               try
               {
  -               retval = super.invoke(method_call);
  +               retval = super.invoke(modification);
                  if (!isActive(tx))
                  {
                     throw new ReplicationException("prepare() failed -- " + "local transaction status is not STATUS_ACTIVE; is " + tx.getStatus());
  @@ -553,7 +486,7 @@
       */
      private Object handleRemoteCommitRollback(MethodCall m, GlobalTransaction gtx) throws Throwable
      {
  -      Transaction ltx = null;
  +      Transaction ltx;
         try
         {
            ltx = getLocalTxForGlobalTx(gtx);
  @@ -654,7 +587,8 @@
       */
      private Object handleCommitRollback(MethodCall m) throws Throwable
      {
  -      GlobalTransaction gtx = findGlobalTransaction(m.getArgs());
  +      //GlobalTransaction gtx = findGlobalTransaction(m.getArgs());
  +      GlobalTransaction gtx = cache.getInvocationContext().getGlobalTransaction();
         Object result;
   
         // this must have a local transaction associated if a prepare has been
  @@ -824,16 +758,6 @@
      //   Private helper methods
      // --------------------------------------------------------------
   
  -   /**
  -    * Tests if a global transaction originated from a different cache in the cluster
  -    *
  -    * @param gtx
  -    * @return true if the gtx is remote, false if it originated locally.
  -    */
  -   private boolean isRemoteGlobalTx(GlobalTransaction gtx)
  -   {
  -      return gtx != null && (gtx.getAddress() != null) && (!gtx.getAddress().equals(cache.getLocalAddress()));
  -   }
   
      /**
       * Creates a gtx (if one doesnt exist), a sync handler, and registers the tx.
  @@ -944,21 +868,6 @@
         return localTx;
      }
   
  -   private void setInvocationContext(Transaction tx, GlobalTransaction gtx)
  -   {
  -      InvocationContext ctx = cache.getInvocationContext();
  -      ctx.setTransaction(tx);
  -      ctx.setGlobalTransaction(gtx);
  -   }
  -
  -   private void scrubInvocationCtx(boolean removeTxs)
  -   {
  -      if (removeTxs) setInvocationContext(null, null);
  -
  -      // only scrub options; not tx and gtx
  -      cache.getInvocationContext().setOptionOverrides(null);
  -   }
  -
      // ------------------------------------------------------------------------
      // Synchronization classes
      // ------------------------------------------------------------------------
  @@ -1000,7 +909,7 @@
         {
            try
            {
  -            setInvocationContext(tx, gtx);
  +            setTransactionalContext(tx, gtx);
               if (log.isTraceEnabled()) log.trace("calling aftercompletion for " + gtx);
               // set any transaction wide options as current for this thread.
               if ((entry = txTable.get(gtx)) != null)
  @@ -1037,7 +946,7 @@
               // clean up the tx table
               txTable.remove(gtx);
               txTable.remove(tx);
  -            scrubInvocationCtx(true);
  +            setTransactionalContext(null, null);
            }
         }
   
  @@ -1061,7 +970,7 @@
            super.beforeCompletion();
            // fetch the modifications before the transaction is committed
            // (and thus removed from the txTable)
  -         setInvocationContext(tx, gtx);
  +         setTransactionalContext(tx, gtx);
            if (modifications.size() == 0)
            {
               if (log.isTraceEnabled()) log.trace("No modifications in this tx.  Skipping beforeCompletion()");
  @@ -1106,7 +1015,7 @@
            finally
            {
               localRollbackOnly = false;
  -            scrubInvocationCtx(false);
  +            setTransactionalContext(null, null);
            }
         }
   
  
  
  
  1.1      date: 2006/09/06 17:58:20;  author: msurtani;  state: Exp;JBossCache/src/org/jboss/cache/interceptors/BaseTransactionalContextInterceptor.java
  
  Index: BaseTransactionalContextInterceptor.java
  ===================================================================
  package org.jboss.cache.interceptors;
  
  import org.jboss.cache.CacheSPI;
  import org.jboss.cache.GlobalTransaction;
  import org.jboss.cache.InvocationContext;
  import org.jboss.cache.TransactionEntry;
  import org.jboss.cache.TransactionTable;
  import org.jboss.cache.config.Option;
  
  import javax.transaction.Transaction;
  import javax.transaction.TransactionManager;
  
  /**
   * Class providing some base functionality around manipulating transactions and global transactions withing invocation contexts.
   *
   * @author <a href="mailto:manik at jboss.org">Manik Surtani</a>
   */
  public abstract class BaseTransactionalContextInterceptor extends Interceptor
  {
     protected TransactionTable txTable;
     protected TransactionManager txManager;
  
     public void setCache(CacheSPI cache)
     {
        super.setCache(cache);
        txManager = cache.getTransactionManager();
        txTable = cache.getTransactionTable();
     }
  
     protected void copyInvocationScopeOptionsToTxScope(InvocationContext ctx)
     {
        // notify the transaction entry that this override is in place.
        TransactionEntry entry = txTable.get(ctx.getGlobalTransaction());
        if (entry != null)
        {
           Option txScopeOption = new Option();
           txScopeOption.setCacheModeLocal(ctx.getOptionOverrides() != null && ctx.getOptionOverrides().isCacheModeLocal());
           entry.setOption(txScopeOption);
        }
     }
  
     protected void setTransactionalContext(Transaction tx, GlobalTransaction gtx)
     {
        InvocationContext ctx = cache.getInvocationContext();
        log.trace("Setting up transactional context.");
        if (log.isTraceEnabled()) log.trace("Setting tx as " + tx + " and gtx as " + gtx);
        ctx.setTransaction(tx);
        ctx.setGlobalTransaction(gtx);
     }
  }
  
  
  



More information about the jboss-cvs-commits mailing list