簡體   English   中英

涉及逐出時,Spring的緩存注釋是否可以安全使用?

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

我正在使用Spring 4.0.3,並利用了EhCache 2.8.1支持的Cache Abstraction功能。

我擔心方法級注釋@Cacheable@CacheEvict在編輯高速緩存時可能無法正確鎖定高速緩存,從而導致線程安全問題。 我在下面的測試似乎證實了這一點。 我的問題是,我是濫用框架還是誤解了測試結果? 還是我得出的結論是,批注不會導致緩存被正確鎖定,因此是否正確,因此使用@CacheEvict不能保證將來的讀取將是有效的?

測試:

創建數據庫表以存儲計數器值

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

在ehcache.xml中創建一個條目以緩存計數器值

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

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

在兩種不同的情況下執行以下三個步驟-首先從控制器方法中刪除緩存注釋,然后再將其添加回

  1. 造訪/incrementcounter
  2. 在一個瀏覽器選項卡中,訪問/viewcounter ,然后在發起此請求后立即在另一個選項卡中訪問/incrementcounter
  3. 造訪/viewcounter

檢測結果

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

緩存結果是錯誤的,是嗎?

緩存抽象中沒有鎖定。 不是第一個要求它的人 ,我們已經在內部進行了廣泛的頭腦風暴,以討論支持它的成本。 事實證明,它遠非簡單,以這種抽象方式使用鎖可能非常棘手,尤其是以“通用”方式。 同樣,緩存供應商花費大量資源來支持此類用例,這是有原因的。

目前,我最好的猜測是,如果您想要這些功能,則需要緩存進行事務處理。 但是,將其與抽象配合使用時有些陷阱,請特別檢查目前正在研究的SPR-11540

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM