【问题标题】:Multiple threads calling the @Cacheable method. Spring cache (3.2.6) is allowing all threads into the method多个线程调用@Cacheable 方法。 Spring cache (3.2.6) 允许所有线程进入方法
【发布时间】:2014-01-30 21:09:30
【问题描述】:

我有一个带有以下类型方法的 DAO 对象。我已将 DAO 注入服务层,并且能够从此 DAO 方法调用中获取缓存结果。但是,当多个线程调用此方法时(在包装 DAO 单例的代理上),其中一些线程仍会从我的数据库中获取数据,即,仍会执行 fetchDataFromDb() 方法调用。有没有办法解决这个问题?这是 Spring 缓存错误吗?

    @Override
    @Cacheable(value = "CacheName")
    public Map<String, DomainObject> fetchDataFromDb() {
    ....
    }

按照我的 Spring 应用程序上下文文件的 XML 配置。这是一个网络应用程序。我使用 JMeter 模拟了多个线程。

<cache:annotation-driven />


<!-- generic cache manager -->
<bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
    <property name="caches">
        <set>
            <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="CacheName" />              
        </set>
    </property>
</bean>

【问题讨论】:

  • 我们可以看看你的 DAO bean 定义吗?是否与缓存配置在同一个上下文中?
  • 您必须在包含 fetchDataFromDb() 方法的类中具有其他方法。确保他们都没有调用 fetchDataFromDb()
  • DAO bean 定义是一个很普通的定义,它连接到数据库并获取一些数据。
  • 我没有直接调用 fetchDataFromDb(),我总是通过 Spring 给定的 bean(我的意思是通过动态代理)。

标签: java multithreading spring caching


【解决方案1】:

你想要的是@Cacheable(sync = true)

【讨论】:

    【解决方案2】:

    我只能找到很少的文档告诉我您所描述的行为是否是错误。然而,在 (http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/html/cache.html) 提供的文档中有一个模糊的提示

    这样,昂贵的方法(无论是 CPU 还是 IO 绑定)对于给定的参数集只能执行一次,结果可以重复使用,而无需再次实际执行该方法

    这里的“can”是有问题的词,因为它可能意味着方法执行“不能多次执行”或者它“只能执行一次”

    我建议您描述的行为不是错误,而是功能上的“缺点”。在我看来,防止对同一组参数多次执行该方法似乎是一种编写死锁的简单方法。

    对此我没有答案,我希望有人能纠正我的假设(因为所描述的行为非常有问题)。

    【讨论】:

    • 好的,经过一些测试,我可以确认这种行为。如果这是一个错误,我从未见过任何报告。我现在强烈怀疑这是一个“功能”。最后一次完成的方法调用将提供将被缓存的对象。当然,在 Cheers 方法中添加同步是没有用的
    • Spring 4.3 增加了对同步缓存的支持:spring.io/blog/2016/03/04/…
    【解决方案3】:

    我猜如果有多个线程在执行时调用这个方法,它们都会命中数据库。

    我看到的最简单的解决方案是让您的服务在同步块中调用 Dao。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多