[infinispan-commits] Infinispan SVN: r170 - in trunk/core/src: main/java/org/infinispan/factories and 3 other directories.

infinispan-commits at lists.jboss.org infinispan-commits at lists.jboss.org
Mon Apr 27 08:38:50 EDT 2009


Author: manik.surtani at jboss.com
Date: 2009-04-27 08:38:50 -0400 (Mon, 27 Apr 2009)
New Revision: 170

Added:
   trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java
   trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
   trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java
   trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java
   trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java
Removed:
   trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
Modified:
   trunk/core/src/main/java/org/infinispan/context/TransactionContext.java
   trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java
   trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
   trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java
   trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
   trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java
Log:
[ISPN-30] (DIST) moved transaction participation tracking to the transaction context rather than the interceptor

Added: trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -0,0 +1,41 @@
+package org.infinispan.context;
+
+import org.infinispan.remoting.transport.Address;
+
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * A transaction context that adds behavior specific to DIST
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class DistTransactionContextImpl extends TransactionContextImpl {
+
+   final Set<Address> participants = new HashSet<Address>();
+
+   public DistTransactionContextImpl(Transaction tx) throws SystemException, RollbackException {
+      super(tx);
+   }
+
+   @Override
+   public Set<Address> getTransactionParticipants() {
+      return participants;
+   }
+
+   @Override
+   public void addTransactionParticipants(Collection<Address> addresses) {
+      participants.addAll(addresses);
+   }
+
+   @Override
+   public void reset() {
+      super.reset();
+      participants.clear();
+   }
+}


Property changes on: trunk/core/src/main/java/org/infinispan/context/DistTransactionContextImpl.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: trunk/core/src/main/java/org/infinispan/context/TransactionContext.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/TransactionContext.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/context/TransactionContext.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -22,10 +22,13 @@
 package org.infinispan.context;
 
 import org.infinispan.commands.write.WriteCommand;
+import org.infinispan.remoting.transport.Address;
 import org.infinispan.transaction.GlobalTransaction;
 
 import javax.transaction.Transaction;
+import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * A context that contains information pertaining to a given transaction.  These contexts typically have the lifespan of
@@ -160,4 +163,20 @@
    void reset();
 
    GlobalTransaction getGobalTransaction();
+
+   /**
+    * Retrieves a set of Addresses of caches participating in a given transaction for a specific cache.  Returns null if
+    * the participation includes <i>all</i> caches in the cluster (e.g., you are using replication, invalidation or
+    * local mode).
+    *
+    * @return a set of cache addresses
+    */
+   Set<Address> getTransactionParticipants();
+
+   /**
+    * Adds a transaction participant.  This has no effect unless the cache mode used is DIST.
+    *
+    * @param addresses address to add
+    */
+   void addTransactionParticipants(Collection<Address> addresses);
 }

Modified: trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/context/TransactionContextImpl.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -23,6 +23,7 @@
 
 import org.infinispan.commands.write.WriteCommand;
 import org.infinispan.container.entries.CacheEntry;
+import org.infinispan.remoting.transport.Address;
 import org.infinispan.transaction.GlobalTransaction;
 import org.infinispan.util.BidirectionalLinkedHashMap;
 
@@ -30,10 +31,12 @@
 import javax.transaction.SystemException;
 import javax.transaction.Transaction;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 
 /**
  * A transaction context specially geared to dealing with MVCC.
@@ -93,6 +96,14 @@
       return gtx;
    }
 
+   public Set<Address> getTransactionParticipants() {
+      return null; // by default all caches in the cluster participate.
+   }
+
+   public void addTransactionParticipants(Collection<Address> addresses) {
+      // no-op - meant for overriding
+   }
+
    public void putLookedUpEntries(Map<Object, CacheEntry> entries) {
       lookedUpEntries.putAll(entries);
    }
@@ -194,10 +205,6 @@
       return hasModifications() || hasLocalModifications();
    }
 
-//   public ReversibleOrderedSet<Object> getKeysLocked() {
-//      return locks == null ? InfinispanCollections.emptyReversibleOrderedSet() : Immutables.immutableReversibleOrderedSetCopy(locks);
-//   }
-
    @Override
    public boolean equals(Object o) {
       if (this == o) return true;

Modified: trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/factories/AbstractComponentRegistry.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -32,6 +32,7 @@
 import org.infinispan.factories.annotations.NonVolatile;
 import org.infinispan.factories.annotations.Start;
 import org.infinispan.factories.annotations.Stop;
+import org.infinispan.factories.context.ContextMetaFactory;
 import org.infinispan.factories.scopes.Scope;
 import org.infinispan.factories.scopes.Scopes;
 import org.infinispan.lifecycle.ComponentStatus;
@@ -156,6 +157,7 @@
       s.add(MarshallerFactory.class);
       s.add(ResponseGeneratorFactory.class);
       s.add(DistributionManagerFactory.class);
+      s.add(ContextMetaFactory.class);
       return s;
    }
 

Modified: trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/factories/EmptyConstructorNamedCacheFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -27,7 +27,6 @@
 import org.infinispan.config.ConfigurationException;
 import org.infinispan.eviction.EvictionManager;
 import org.infinispan.factories.annotations.DefaultFactoryFor;
-import org.infinispan.factories.context.ContextFactory;
 import org.infinispan.invocation.InvocationContextContainer;
 import org.infinispan.loader.CacheLoaderManager;
 import org.infinispan.marshall.Marshaller;
@@ -44,8 +43,7 @@
  */
 @DefaultFactoryFor(classes = {CacheNotifier.class, EntryFactory.class, CommandsFactory.class,
                               CacheLoaderManager.class, InvocationContextContainer.class,
-                              TransactionTable.class, BatchContainer.class, ContextFactory.class,
-                              TransactionLog.class, EvictionManager.class})
+                              TransactionTable.class, BatchContainer.class, TransactionLog.class, EvictionManager.class})
 public class EmptyConstructorNamedCacheFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
    @Override
    public <T> T construct(Class<T> componentType) {

Deleted: trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -1,59 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source.
- * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
- * as indicated by the @author tags. See the copyright.txt file in the
- * distribution for a full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.infinispan.factories.context;
-
-import org.infinispan.context.InvocationContext;
-import org.infinispan.context.InvocationContextImpl;
-import org.infinispan.context.TransactionContext;
-import org.infinispan.context.TransactionContextImpl;
-
-import javax.transaction.RollbackException;
-import javax.transaction.SystemException;
-import javax.transaction.Transaction;
-
-/**
- * This is the factory responsible for creating {@link InvocationContext}s and {@link TransactionContext}s for requests,
- * based on the configuration used.
- *
- * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
- * @since 4.0
- */
-public class ContextFactory {
-   /**
-    * @return a new invocation context
-    */
-   public InvocationContext createInvocationContext() {
-      return new InvocationContextImpl();
-   }
-
-   /**
-    * @param tx JTA transaction to associate the new context with
-    * @return a new transaction context
-    * @throws javax.transaction.RollbackException
-    *          in the event of an invalid transaaction
-    * @throws javax.transaction.SystemException
-    *          in the event of an invalid transaction
-    */
-   public TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException {
-      return new TransactionContextImpl(tx);
-   }
-}
\ No newline at end of file

Added: trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -0,0 +1,36 @@
+package org.infinispan.factories.context;
+
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.TransactionContext;
+import org.infinispan.factories.scopes.Scope;
+import org.infinispan.factories.scopes.Scopes;
+
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+/**
+ * A factory for contexts
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+ at Scope(Scopes.NAMED_CACHE)
+public interface ContextFactory {
+
+   /**
+    * @return a new invocation context
+    */
+   InvocationContext createInvocationContext();
+
+
+   /**
+    * @param tx JTA transaction to associate the new context with
+    * @return a new transaction context
+    * @throws javax.transaction.RollbackException
+    *          in the event of an invalid transaaction
+    * @throws javax.transaction.SystemException
+    *          in the event of an invalid transaction
+    */
+   TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException;
+}

Added: trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -0,0 +1,23 @@
+package org.infinispan.factories.context;
+
+import org.infinispan.factories.AbstractNamedCacheComponentFactory;
+import org.infinispan.factories.AutoInstantiableFactory;
+import org.infinispan.factories.annotations.DefaultFactoryFor;
+
+/**
+ * Builds a context factory
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+ at DefaultFactoryFor(classes = ContextFactory.class)
+public class ContextMetaFactory extends AbstractNamedCacheComponentFactory implements AutoInstantiableFactory {
+
+   @SuppressWarnings("unchecked")
+   public <T> T construct(Class<T> componentType) {
+      if (configuration.getCacheMode().isDistributed())
+         return (T) new DistContextFactory();
+      else
+         return (T) new DefaultContextFactory();
+   }
+}


Property changes on: trunk/core/src/main/java/org/infinispan/factories/context/ContextMetaFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Copied: trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java (from rev 169, trunk/core/src/main/java/org/infinispan/factories/context/ContextFactory.java)
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -0,0 +1,59 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2000 - 2008, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.infinispan.factories.context;
+
+import org.infinispan.context.InvocationContext;
+import org.infinispan.context.InvocationContextImpl;
+import org.infinispan.context.TransactionContext;
+import org.infinispan.context.TransactionContextImpl;
+
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+/**
+ * This is the factory responsible for creating {@link InvocationContext}s and {@link TransactionContext}s for requests,
+ * based on the configuration used.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 4.0
+ */
+public class DefaultContextFactory implements ContextFactory {
+   /**
+    * @return a new invocation context
+    */
+   public InvocationContext createInvocationContext() {
+      return new InvocationContextImpl();
+   }
+
+   /**
+    * @param tx JTA transaction to associate the new context with
+    * @return a new transaction context
+    * @throws javax.transaction.RollbackException
+    *          in the event of an invalid transaaction
+    * @throws javax.transaction.SystemException
+    *          in the event of an invalid transaction
+    */
+   public TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException {
+      return new TransactionContextImpl(tx);
+   }
+}
\ No newline at end of file


Property changes on: trunk/core/src/main/java/org/infinispan/factories/context/DefaultContextFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Added: trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java	                        (rev 0)
+++ trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -0,0 +1,22 @@
+package org.infinispan.factories.context;
+
+import org.infinispan.context.DistTransactionContextImpl;
+import org.infinispan.context.TransactionContext;
+
+import javax.transaction.RollbackException;
+import javax.transaction.SystemException;
+import javax.transaction.Transaction;
+
+/**
+ * A context factory specific to DIST contexts
+ *
+ * @author Manik Surtani
+ * @since 4.0
+ */
+public class DistContextFactory extends DefaultContextFactory {
+
+   @Override
+   public TransactionContext createTransactionContext(Transaction tx) throws SystemException, RollbackException {
+      return new DistTransactionContextImpl(tx);
+   }
+}


Property changes on: trunk/core/src/main/java/org/infinispan/factories/context/DistContextFactory.java
___________________________________________________________________
Name: svn:keywords
   + Id Revision
Name: svn:eol-style
   + LF

Modified: trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java
===================================================================
--- trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/main/java/org/infinispan/interceptors/DistributionInterceptor.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -1,7 +1,6 @@
 package org.infinispan.interceptors;
 
 import org.infinispan.commands.CommandsFactory;
-import org.infinispan.commands.DataCommand;
 import org.infinispan.commands.read.GetKeyValueCommand;
 import org.infinispan.commands.tx.CommitCommand;
 import org.infinispan.commands.tx.PrepareCommand;
@@ -20,15 +19,14 @@
 import org.infinispan.factories.annotations.Inject;
 import org.infinispan.interceptors.base.BaseRpcInterceptor;
 import org.infinispan.remoting.transport.Address;
-import org.infinispan.transaction.GlobalTransaction;
 import org.infinispan.util.Immutables;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
 
 /**
  * The interceptor that handles distribution of entries across a cluster, as well as transparent lookup
@@ -39,8 +37,6 @@
 public class DistributionInterceptor extends BaseRpcInterceptor {
    DistributionManager dm;
    CommandsFactory cf;
-   // TODO move this to the transaction context.  Will scale better there.
-   private final Map<GlobalTransaction, List<Address>> txRecipients = new ConcurrentHashMap<GlobalTransaction, List<Address>>();
    static final RecipientGenerator CLEAR_COMMAND_GENERATOR = new RecipientGenerator() {
       private final Object[] EMPTY_ARRAY = {};
 
@@ -135,15 +131,11 @@
    // ---- TX boundard commands
    @Override
    public Object visitCommitCommand(InvocationContext ctx, CommitCommand command) throws Throwable {
-      try {
-         if (!skipReplicationOfTransactionMethod(ctx)) {
-            List<Address> recipients = txRecipients.get(command.getGlobalTransaction());
-            if (recipients != null) replicateCall(ctx, recipients, command, configuration.isSyncCommitPhase(), true);
-         }
-         return invokeNextInterceptor(ctx, command);
-      } finally {
-         txRecipients.remove(command.getGlobalTransaction());
+      if (!skipReplicationOfTransactionMethod(ctx)) {
+         List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
+         replicateCall(ctx, recipients, command, configuration.isSyncCommitPhase(), true);
       }
+      return invokeNextInterceptor(ctx, command);
    }
 
    @Override
@@ -163,8 +155,7 @@
                       rpcManager.getTransport().getAddress(), command.getGlobalTransaction(), sync);
          }
 
-         List<Address> recipients = determineRecipients(command);
-         txRecipients.put(command.getGlobalTransaction(), recipients);
+         List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
 
          // this method will return immediately if we're the only member (because exclude_self=true)
          replicateCall(ctx, recipients, command, sync, false);
@@ -175,37 +166,13 @@
 
    @Override
    public Object visitRollbackCommand(InvocationContext ctx, RollbackCommand command) throws Throwable {
-      try {
-         if (!skipReplicationOfTransactionMethod(ctx) && !ctx.isLocalRollbackOnly()) {
-            List<Address> recipients = txRecipients.get(command.getGlobalTransaction());
-            if (recipients != null) replicateCall(ctx, recipients, command, configuration.isSyncRollbackPhase(), true);
-         }
-         return invokeNextInterceptor(ctx, command);
-      } finally {
-         txRecipients.remove(command.getGlobalTransaction());
+      if (!skipReplicationOfTransactionMethod(ctx) && !ctx.isLocalRollbackOnly()) {
+         List<Address> recipients = new ArrayList<Address>(ctx.getTransactionContext().getTransactionParticipants());
+         replicateCall(ctx, recipients, command, configuration.isSyncRollbackPhase(), true);
       }
+      return invokeNextInterceptor(ctx, command);
    }
 
-   private List<Address> determineRecipients(PrepareCommand cmd) {
-      Set<Address> r = new HashSet<Address>();
-      boolean toAll = false;
-      for (WriteCommand c : cmd.getModifications()) {
-         if (c instanceof ClearCommand) {
-            toAll = true;
-            break;
-         } else {
-            if (c instanceof DataCommand) {
-               r.addAll(dm.locate(((DataCommand) c).getKey()));
-            } else if (c instanceof PutMapCommand) {
-               r.addAll(new MultipleKeysRecipientGenerator(((PutMapCommand) c).getMap().keySet()).generateRecipients());
-            }
-         }
-      }
-
-      return toAll ? null : Immutables.immutableListConvert(r);
-   }
-
-
    private void remoteGetBeforeWrite(InvocationContext ctx, Object... keys) throws Throwable {
       // only do this if we are sync (OR if we dont care about return values!)
 //      if (!configuration.isUnsafeUnreliableReturnValues()) {
@@ -221,23 +188,32 @@
       boolean local = isLocalModeForced(ctx);
       // see if we need to load values from remote srcs first
       remoteGetBeforeWrite(ctx, recipientGenerator.getKeys());
+
+      // if this is local mode then skip distributing
       if (local && ctx.getTransaction() == null) return invokeNextInterceptor(ctx, command);
-      // FIRST pass this call up the chain.  Only if it succeeds (no exceptions) locally do we attempt to replicate.
 
+      // FIRST pass this call up the chain.  Only if it succeeds (no exceptions) locally do we attempt to distribute.
       Object returnValue = invokeNextInterceptor(ctx, command);
 
       if (command.isSuccessful()) {
-         if (ctx.getTransaction() == null && ctx.isOriginLocal()) {
-            List<Address> rec = recipientGenerator.generateRecipients();
-            if (trace) log.trace("Invoking command {0} on hosts {1}", command, rec);
-            // if L1 caching is used make sure we broadcast an invalidate message
-            if (configuration.isL1CacheEnabled() && rec != null) {
-               InvalidateCommand ic = cf.buildInvalidateFromL1Command(recipientGenerator.getKeys());
-               replicateCall(ctx, ic, isSynchronous(ctx), false);
+         if (ctx.getTransaction() == null) {
+            if (ctx.isOriginLocal()) {
+               List<Address> rec = recipientGenerator.generateRecipients();
+               if (trace) log.trace("Invoking command {0} on hosts {1}", command, rec);
+               // if L1 caching is used make sure we broadcast an invalidate message
+               if (configuration.isL1CacheEnabled() && rec != null) {
+                  InvalidateCommand ic = cf.buildInvalidateFromL1Command(recipientGenerator.getKeys());
+                  replicateCall(ctx, ic, isSynchronous(ctx), false);
+               }
+               replicateCall(ctx, rec, command, isSynchronous(ctx), false);
             }
-            replicateCall(ctx, rec, command, isSynchronous(ctx), false);
          } else {
-            if (local) ctx.getTransactionContext().addLocalModification(command);
+            if (local) {
+               ctx.getTransactionContext().addLocalModification(command);
+            } else {
+               // add to list of participants
+               ctx.getTransactionContext().addTransactionParticipants(recipientGenerator.generateRecipients());
+            }
          }
       }
       return returnValue;

Modified: trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java
===================================================================
--- trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java	2009-04-24 18:15:21 UTC (rev 169)
+++ trunk/core/src/test/java/org/infinispan/notifications/cachelistener/CacheNotifierImplTest.java	2009-04-27 12:38:50 UTC (rev 170)
@@ -5,7 +5,7 @@
 import org.infinispan.Cache;
 import org.infinispan.context.InvocationContext;
 import org.infinispan.context.InvocationContextImpl;
-import org.infinispan.factories.context.ContextFactory;
+import org.infinispan.factories.context.DefaultContextFactory;
 import org.infinispan.invocation.InvocationContextContainer;
 import org.infinispan.notifications.cachelistener.event.CacheEntryEvent;
 import org.infinispan.notifications.cachelistener.event.CacheEntryModifiedEvent;
@@ -31,7 +31,7 @@
       mockCache = createNiceMock(Cache.class);
       EasyMock.replay(mockCache);
       InvocationContextContainer icc = new InvocationContextContainer();
-      icc.injectContextFactory(new ContextFactory());
+      icc.injectContextFactory(new DefaultContextFactory());
       n.injectDependencies(icc, mockCache);
       cl = new CacheListener();
       n.start();




More information about the infinispan-commits mailing list