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

Sai*_*aka 6 java spring multithreading caching

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

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

遵循我的 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>
Run Code Online (Sandbox Code Playgroud)

小智 8

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


小智 3

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

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

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

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

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