diff --git c/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java w/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
index c96e833..93944ab 100644
--- c/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
+++ w/src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java
@@ -587,6 +587,14 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
             IvyPatternHelper.substitute(
                 getDataFilePattern(), mRevId)), "ivy cached data file for " + mRevId);
     }
+    
+    /** A resolver-specific ivydata file, only used for caching dynamic revisions, e.g. integration-repo. */
+    private PropertiesFile getCachedDataFile(String resolverName, ModuleRevisionId mRevId) {
+        // we cheat and append ".${resolverName} onto the end of the regular ivydata location
+        return new PropertiesFile(new File(getRepositoryCacheRoot(), 
+            IvyPatternHelper.substitute(
+                getDataFilePattern(), mRevId) + "." + resolverName), "ivy cached data file for " + mRevId);
+    }
 
     public ResolvedModuleRevision findModuleInCache(
             DependencyDescriptor dd, ModuleRevisionId requestedRevisionId, 
@@ -614,7 +622,7 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
         
         try {
             if (settings.getVersionMatcher().isDynamic(mrid)) {
-                String resolvedRevision = getResolvedRevision(mrid, options);
+                String resolvedRevision = getResolvedRevision(expectedResolver, mrid, options);
                 if (resolvedRevision != null) {
                     Message.verbose("found resolved revision in cache: " 
                         + mrid + " => " + resolvedRevision);
@@ -678,6 +686,9 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
                             return new ResolvedModuleRevision(
                                 resolver, artResolver, depMD, madr);
                         } else {
+                            // Note: after adding per-resolver dynamic revision caching, it seems like this check can
+                            // go away. (Previously this is how Ivy would find latest.integration=1.1 while looking in
+                            // resolver1, but 1.1 was actually the latest.itegration for resolver2.)
                             Message.debug(
                                 "found module in cache but with a different resolver: "
                                 + "discarding: " + mrid 
@@ -736,8 +747,8 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
         return cache.getStale(ivyFile, settings, options.isValidate(), mdProvider);
     }
 
-    
-    private String getResolvedRevision(ModuleRevisionId mrid, CacheMetadataOptions options) {
+    /** Called by doFindModuleInCache to lookup the dynamic {@code mrid} in the ivycache's ivydata file. */
+    private String getResolvedRevision(String expectedResolver, ModuleRevisionId mrid, CacheMetadataOptions options) {
         if (!lockMetadataArtifact(mrid)) {
             Message.error("impossible to acquire lock for " + mrid);
             return null;
@@ -748,7 +759,13 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
                 Message.verbose("refresh mode: no check for cached resolved revision for " + mrid);
                 return null;
             }
-            PropertiesFile cachedResolvedRevision = getCachedDataFile(mrid);
+            // If a resolver is asking for its specific dynamic revision, avoid looking at a different one
+            PropertiesFile cachedResolvedRevision;
+            if (expectedResolver != null) {
+                cachedResolvedRevision = getCachedDataFile(expectedResolver, mrid);
+            } else {
+                cachedResolvedRevision = getCachedDataFile(mrid);
+            }
             resolvedRevision = cachedResolvedRevision.getProperty("resolved.revision");
             if (resolvedRevision == null) {
                 Message.verbose(getName() + ": no cached resolved revision for " + mrid);
@@ -777,15 +794,27 @@ public class DefaultRepositoryCacheManager implements RepositoryCacheManager, Iv
     }
 
     public void saveResolvedRevision(ModuleRevisionId mrid, String revision) {
+        saveResolvedRevision(null, mrid, revision);
+    }
+
+    public void saveResolvedRevision(String resolverName, ModuleRevisionId mrid, String revision) {
         if (!lockMetadataArtifact(mrid)) {
             Message.error("impossible to acquire lock for " + mrid);
             return;
         }
         try {
-            PropertiesFile cachedResolvedRevision = getCachedDataFile(mrid);
+            PropertiesFile cachedResolvedRevision;
+            if (resolverName == null) {
+                cachedResolvedRevision = getCachedDataFile(mrid);
+            } else {
+                cachedResolvedRevision = getCachedDataFile(resolverName, mrid);
+            }
             cachedResolvedRevision.setProperty(
                 "resolved.time", String.valueOf(System.currentTimeMillis()));
             cachedResolvedRevision.setProperty("resolved.revision", revision);
+            if (resolverName != null) {
+                cachedResolvedRevision.setProperty("resolver", resolverName);
+            }
             cachedResolvedRevision.save();
         } finally {
             unlockMetadataArtifact(mrid);
diff --git c/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java w/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
index cbd9ef7..19540e5 100644
--- c/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
+++ w/src/java/org/apache/ivy/core/cache/RepositoryCacheManager.java
@@ -187,7 +187,18 @@ public interface RepositoryCacheManager {
      * 
      * @param dynamicMrid the dynamic module revision id
      * @param revision the resolved revision
+     * @deprecated See {@link #saveResolvedRevision(String, ModuleRevisionId, String)} which prevents cache
+     *  thrashing when multiple resolvers store the same dynamicMrid
      */
     public void saveResolvedRevision(ModuleRevisionId dynamicMrid, String revision);
     
+    /**
+     * Caches a dynamic revision constraint resolution for a specific resolver.
+     * 
+     * @param resolverName the resolver in which this dynamic revision was resolved
+     * @param dynamicMrid the dynamic module revision id
+     * @param revision the resolved revision
+     */
+    public void saveResolvedRevision(String resolverName, ModuleRevisionId dynamicMrid, String revision);
+    
 }
diff --git c/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java w/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
index 858fffc..3ab8e71 100644
--- c/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
+++ w/src/java/org/apache/ivy/plugins/resolver/AbstractResolver.java
@@ -524,23 +524,23 @@ public abstract class AbstractResolver
             ResolveData data) {
         Checks.checkNotNull(dd, "dd");
         Checks.checkNotNull(data, "data");
-        
+
+        // always cache dynamic mrids because we can store per-resolver values
+        saveModuleRevisionIfNeeded(dd, newModuleFound);
+
         // check if latest is asked and compare to return the most recent
         ResolvedModuleRevision previousModuleFound = data.getCurrentResolvedModuleRevision();
         String newModuleDesc = describe(newModuleFound);
         Message.debug("\tchecking " + newModuleDesc + " against " + describe(previousModuleFound));
         if (previousModuleFound == null) {
             Message.debug("\tmodule revision kept as first found: " + newModuleDesc);
-            saveModuleRevisionIfNeeded(dd, newModuleFound);
             return newModuleFound;
         } else if (isAfter(newModuleFound, previousModuleFound, data.getDate())) {
             Message.debug("\tmodule revision kept as younger: " + newModuleDesc);
-            saveModuleRevisionIfNeeded(dd, newModuleFound);
             return newModuleFound;
         } else if (!newModuleFound.getDescriptor().isDefault() 
                 && previousModuleFound.getDescriptor().isDefault()) {
             Message.debug("\tmodule revision kept as better (not default): " + newModuleDesc);
-            saveModuleRevisionIfNeeded(dd, newModuleFound);
             return newModuleFound;
         } else {
             Message.debug("\tmodule revision discarded as older: " + newModuleDesc);
@@ -553,7 +553,7 @@ public abstract class AbstractResolver
         if (newModuleFound != null 
                 && getSettings().getVersionMatcher().isDynamic(dd.getDependencyRevisionId())) {
             getRepositoryCacheManager().saveResolvedRevision(
-                dd.getDependencyRevisionId(), newModuleFound.getId().getRevision());
+                getName(), dd.getDependencyRevisionId(), newModuleFound.getId().getRevision());
         }
     }
 
diff --git c/test/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManagerTest.java w/test/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManagerTest.java
index af5c61a..9da06fc 100644
--- c/test/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManagerTest.java
+++ w/test/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManagerTest.java
@@ -18,33 +18,55 @@
 package org.apache.ivy.core.cache;
 
 import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.text.ParseException;
 import java.util.Date;
 
 import junit.framework.TestCase;
 
 import org.apache.ivy.Ivy;
+import org.apache.ivy.core.IvyContext;
 import org.apache.ivy.core.module.descriptor.Artifact;
 import org.apache.ivy.core.module.descriptor.DefaultArtifact;
+import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
+import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
 import org.apache.ivy.core.module.id.ModuleId;
 import org.apache.ivy.core.module.id.ModuleRevisionId;
+import org.apache.ivy.core.resolve.ResolvedModuleRevision;
 import org.apache.ivy.core.settings.IvySettings;
+import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
+import org.apache.ivy.plugins.repository.BasicResource;
+import org.apache.ivy.plugins.repository.Resource;
+import org.apache.ivy.plugins.repository.ResourceDownloader;
+import org.apache.ivy.plugins.resolver.MockResolver;
+import org.apache.ivy.plugins.resolver.util.ResolvedResource;
+import org.apache.ivy.util.DefaultMessageLogger;
+import org.apache.ivy.util.FileUtil;
+import org.apache.ivy.util.Message;
 import org.apache.tools.ant.Project;
 import org.apache.tools.ant.taskdefs.Delete;
+import org.apache.tools.ant.util.FileUtils;
 
 /**
  * @see DefaultResolutionCacheManager
  */
 public class DefaultRepositoryCacheManagerTest extends TestCase {
+    
     private DefaultRepositoryCacheManager cacheManager;
-
     private Artifact artifact;
-
     private ArtifactOrigin origin;
+    private Ivy ivy;
 
     protected void setUp() throws Exception {
         File f = File.createTempFile("ivycache", ".dir");
-        Ivy ivy = new Ivy();
+        ivy = new Ivy();
         ivy.configureDefault();
+        ivy.getLoggerEngine().setDefaultLogger(new DefaultMessageLogger(Message.MSG_DEBUG));
+        IvyContext.pushNewContext().setIvy(ivy);
+        
         IvySettings settings = ivy.getSettings();
         f.delete(); // we want to use the file as a directory, so we delete the file itself
         cacheManager = new DefaultRepositoryCacheManager();
@@ -57,6 +79,7 @@ public class DefaultRepositoryCacheManagerTest extends TestCase {
     }
 
     protected void tearDown() throws Exception {
+        IvyContext.popContext();
         Delete del = new Delete();
         del.setProject(new Project());
         del.setDir(cacheManager.getRepositoryCacheRoot());
@@ -100,7 +123,58 @@ public class DefaultRepositoryCacheManagerTest extends TestCase {
         assertTrue(ArtifactOrigin.isUnknown(found));
     }
 
-    protected Artifact createArtifact(String org, String module, String rev, String name,
+    public void testLatestIntegrationIsCachedPerResolver() throws Exception {
+        // given a module org#module
+        ModuleId mi = new ModuleId("org", "module");
+
+        // and a latest.integration mrid/dd
+        ModuleRevisionId mridLatest = new ModuleRevisionId(mi, "trunk", "latest.integration");
+        DependencyDescriptor ddLatest = new DefaultDependencyDescriptor(mridLatest,  false);
+
+        // and some random options
+        CacheMetadataOptions options = new CacheMetadataOptions().setCheckTTL(false);
+
+        // setup resolver1 to download the static content so we can call cacheModuleDescriptor
+        MockResolver resolver1 = new MockResolver();
+        resolver1.setName("resolver1");
+        resolver1.setSettings(ivy.getSettings());
+        ivy.getSettings().addResolver(resolver1);
+        ResourceDownloader downloader = new ResourceDownloader() {
+            public void download(Artifact artifact, Resource resource, File dest)
+                    throws IOException {
+                String content = "<ivy-module version=\"2.0\"><info organisation=\"org\" module=\"module\" status=\"integration\" revision=\"1.1\" branch=\"trunk\"/></ivy-module>";
+                dest.getParentFile().mkdirs();
+                FileOutputStream out = new FileOutputStream(dest);
+                PrintWriter pw = new PrintWriter(out);
+                pw.write(content);
+                pw.flush();
+                out.close();
+            }
+        };
+        ModuleDescriptorWriter writer = new ModuleDescriptorWriter() {
+            public void write(ResolvedResource originalMdResource, ModuleDescriptor md, File src, File dest) throws IOException, ParseException {
+                XmlModuleDescriptorWriter.write(md, dest);
+            }
+        };
+
+        // latest.integration will resolve to 1.1 in resolver1
+        ModuleRevisionId mrid11 = new ModuleRevisionId(mi, "trunk", "1.1");
+        DependencyDescriptor dd11 = new DefaultDependencyDescriptor(mrid11,  false);
+        DefaultArtifact artifact11 = new DefaultArtifact(mrid11, new Date(), "module-1.1.ivy", "ivy", "ivy", true);
+        BasicResource resource11 = new BasicResource("/module-1-1.ivy", true, 1, 0, true);
+        ResolvedResource mdRef11 = new ResolvedResource(resource11, "1.1");
+
+        // tell the cache about 1.1
+        ResolvedModuleRevision rmr11 = cacheManager.cacheModuleDescriptor(resolver1, mdRef11, dd11, artifact11, downloader, options);
+        cacheManager.originalToCachedModuleDescriptor(resolver1, mdRef11, artifact11, rmr11, writer);
+        // and use the new overload that passes in resolver name
+        cacheManager.saveResolvedRevision("resolver1", mridLatest, "1.1");
+
+        ResolvedModuleRevision rmrFromCache = cacheManager.findModuleInCache(ddLatest, mridLatest, options, "resolver1");
+        assertEquals(rmr11, rmrFromCache);
+    }
+
+    protected static DefaultArtifact createArtifact(String org, String module, String rev, String name,
             String type, String ext) {
         ModuleId mid = new ModuleId(org, module);
         ModuleRevisionId mrid = new ModuleRevisionId(mid, rev);
