java - 当涉及驱逐时,Spring 的缓存注解是否可以安全使用?

标签 java spring caching spring-cache

我正在使用 Spring 4.0.3,并利用由 EhCache 2.8.1 支持的缓存抽象功能。

我担心方法级注释 @Cacheable@CacheEvict 在编辑缓存时可能无法正确锁定缓存,从而导致线程安全问题。我下面的测试似乎证实了这一点。我的问题是,我是在滥用框架还是误解了我的测试结果?还是我得出的结论是注释不会导致缓存被正确锁定,因此使用 @CacheEvict 不能保证 future 的读取有效?

测试:

创建一个数据库表来存储计数器值

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

在 ehcache.xml 中创建一个条目来缓存计数器值

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

在Spring Controller 中创建两个请求映射方法——一个读取计数器的值并在长时间延迟后返回,另一个增加值然后快速返回

@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;
}

在两种不同的情况下执行这三个步骤——首先从 Controller 方法中删除缓存注释,然后将它们添加回

  1. 访问/incrementcounter
  2. 在一个浏览器选项卡中,访问/viewcounter,然后在发起此请求后立即在另一个选项卡中访问/incrementcounter
  3. 访问/viewcounter

测试结果

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

with-caching 结果是错误的,是吗?

最佳答案

缓存抽象中没有锁定。你是not the first one asking for it我们已经在内部就支持它的成本进行了重要的集思广益。事实证明,它远非简单,在这种抽象中使用锁可能非常棘手,尤其是在“通用”方式下。此外,缓存供应商花费大量资源来支持此类用例,这是有原因的。

我目前最好的猜测是,如果您想要这些功能,您需要您的缓存是事务性的。虽然将它与抽象一起使用时有一些问题,请特别检查 SPR-11540目前正在处理中。

关于java - 当涉及驱逐时,Spring 的缓存注解是否可以安全使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23830193/

相关文章:

java - 图形/网络数据结构的 Java API 列表

java - 上传图片,编码为base64 Spring MVC

java - 适用于 Android 的 Spring : REST server

java - (没有为参数4指定值)多对多关系错误

python - 为什么 functools.lru_cache 在处理普通方法时不缓存 __call__

caching - Varnish 缓存和标题

caching - Redis 同步失败。 Redis 复制键和值有效

java - 在 REDIS 中存储 Java Date 对象

java - 在java中将HTML表格写入PDF

Java GUI 对话框超链接