调用@Cacheable方法的多个线程。 Spring cache(3.2.6)允许所有线程进入该方法

时间:2014-01-30 21:09:30

标签: java multithreading spring caching

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

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

遵循我的Spring应用程序上下文文件的XML配置。这是一个Web应用程序。我使用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>

3 个答案:

答案 0 :(得分:3)

我只能找到一些文档告诉我你所描述的行为是否是一个错误。然而,有一个模糊的提示,它将出现在(http://docs.spring.io/spring/docs/4.0.0.RELEASE/spring-framework-reference/html/cache.html

提供的文件中
  

这样,昂贵的方法(无论是CPU还是IO绑定)只能对给定的一组参数执行一次,并且重用结果而不必再次实际执行该方法

&#34; can&#34;这是一个有问题的词,因为它可能意味着方法执行不能超过一次&#34;或者它只能执行一次&#34;

我建议您描述的行为不是错误,而是功能性的缺点&#34;。对于同一组参数,防止该方法被执行多次似乎是一种简单的方法来编写死锁。

我对此没有答案,我希望有人会纠正我的假设(因为描述的行为很成问题)。

答案 1 :(得分:1)

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

答案 2 :(得分:0)

我想如果多个线程在执行时调用此方法,则所有这些线程都会命中数据库。

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