简体   繁体   English

涉及逐出时,Spring的缓存注释是否可以安全使用?

[英]Are Spring's cache annotations safe to use when evictions are involved?

I am using Spring 4.0.3, and utilizing the Cache Abstraction feature, backed by EhCache 2.8.1. 我正在使用Spring 4.0.3,并利用了EhCache 2.8.1支持的Cache Abstraction功能。

I was concerned that the method-level annotations @Cacheable and @CacheEvict may not properly lock the cache while editing it, resulting in thread safety problems. 我担心方法级注释@Cacheable@CacheEvict在编辑高速缓存时可能无法正确锁定高速缓存,从而导致线程安全问题。 My test below seems to confirm that. 我在下面的测试似乎证实了这一点。 My question is, am I misusing the framework or misinterpreting the results of my test? 我的问题是,我是滥用框架还是误解了测试结果? Or am I correct in concluding that the annotations do not cause the cache to be properly locked, and therefore the use of @CacheEvict does not guarantee that future reads will be valid? 还是我得出的结论是,批注不会导致缓存被正确锁定,因此是否正确,因此使用@CacheEvict不能保证将来的读取将是有效的?

Test: 测试:

Create a database table to store a counter value 创建数据库表以存储计数器值

create table counter
(
    counter integer
);
insert into counter values(0);

Create an entry in ehcache.xml to cache the counter value 在ehcache.xml中创建一个条目以缓存计数器值

<cache name="counter"
    eternal="true"
    maxElementsInMemory="1"/>

Create two request mapping methods in a Spring controller -- one to read the value of the counter and return after a long delay, and the other to increment the value and then return quickly 在Spring控制器中创建两种请求映射方法-一种读取计数器的值并在长时间延迟后返回,另一种递增该值然后快速返回

@RequestMapping("/viewcounter")
@ResponseBody
@Cacheable(value = "counter", key = "1")
public int readCounter() {
    int count = dao.selectInteger("select counter from counter");
    try {
        Thread.sleep(5000);
    }
    catch (InterruptedException e) {
        throw new RuntimeException(e);
    }
    return count;
}

@RequestMapping("/incrementcounter")
@ResponseBody
@CacheEvict(value = "counter", key = "1")
public int incrementCounter() {
    dao.update("update counter set counter = counter + 1");
    int count = dao.selectInteger("select counter from counter");
    return count;
}

Follow these three steps under two different scenarios -- first with the cache annotations removed from the controller methods, and then with them added back in 在两种不同的情况下执行以下三个步骤-首先从控制器方法中删除缓存注释,然后再将其添加回

  1. Visit /incrementcounter 造访/incrementcounter
  2. In one browser tab, visit /viewcounter , and then immediately after initiating this request, visit /incrementcounter in another tab 在一个浏览器选项卡中,访问/viewcounter ,然后在发起此请求后立即在另一个选项卡中访问/incrementcounter
  3. Visit /viewcounter 造访/viewcounter

Test results 检测结果

Expected result: 2
Actual result without caching: 2
Actual result with caching: 1

The with-caching result is wrong, yes? 缓存结果是错误的,是吗?

There's no locking in the cache abstraction. 缓存抽象中没有锁定。 You are not the first one asking for it and we already had significant brainstorming internally of what it would cost to support it. 不是第一个要求它的人 ,我们已经在内部进行了广泛的头脑风暴,以讨论支持它的成本。 It turns out that it is far from being simple and playing with locks in such abstraction may be very tricky, especially in a "generic" way. 事实证明,它远非简单,以这种抽象方式使用锁可能非常棘手,尤其是以“通用”方式。 Also, cache vendors spend a significant amount of resources to support these kind of use cases and there's a reason for that. 同样,缓存供应商花费大量资源来支持此类用例,这是有原因的。

My best guess at it for the moment is that if you want these features, you need your cache to be transactional. 目前,我最好的猜测是,如果您想要这些功能,则需要缓存进行事务处理。 There are some gotcha when using it with the abstraction though, check in particular SPR-11540 which is being worked on at the moment. 但是,将其与抽象配合使用时有些陷阱,请特别检查目前正在研究的SPR-11540

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 spring 引导缓存注释在使用 Redis 进行缓存的应用程序中的作用是什么? - What's the role of spring boot cache annotations in a application which use Redis for caching? 使用自定义刷新和逐出Java在DAO上缓存实现 - cache implementation on DAO with custom refresh and evictions java 对Spring注释的依赖 - Dependency on Spring's annotations 是否可以使用Spring的注释为Elasticsearch中的映射定义Completion Suggester? - Is it possible to use Spring's annotations to define Completion Suggester for a mapping in Elasticsearch? Spring + Hibernate Web应用程序-何时使用缓存? - Spring + Hibernate web application - When to use cache? 类对象为新对象时无法使用@spring批注 - Unable to use @spring annotations when class object is new 涉及GUI时,程序立即终止 - Program terminates immediately when GUI's are involved 如何使用 Spring 的 @Cacheable 和 Aerospike 作为缓存? - How do I use Spring's @Cacheable with Aerospike as the cache? Java的“字符串”哈希码函数是否是线程安全的,如果它的缓存设置器不使用锁? - Is Java's “String” hashcode function thread-safe if its cache setter does not use locks? 缓存 AmazonS3 客户端以备后用是否安全? - Is it safe to cache AmazonS3 client for later use?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM