[英]What's the role of spring boot cache annotations in a application which use Redis for caching?
[英]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;
}
在兩種不同的情況下執行以下三個步驟-首先從控制器方法中刪除緩存注釋,然后再將其添加回
/incrementcounter
/viewcounter
,然后在發起此請求后立即在另一個選項卡中訪問/incrementcounter
/viewcounter
檢測結果
Expected result: 2
Actual result without caching: 2
Actual result with caching: 1
緩存結果是錯誤的,是嗎?
緩存抽象中沒有鎖定。 您不是第一個要求它的人 ,我們已經在內部進行了廣泛的頭腦風暴,以討論支持它的成本。 事實證明,它遠非簡單,以這種抽象方式使用鎖可能非常棘手,尤其是以“通用”方式。 同樣,緩存供應商花費大量資源來支持此類用例,這是有原因的。
目前,我最好的猜測是,如果您想要這些功能,則需要緩存進行事務處理。 但是,將其與抽象配合使用時有些陷阱,請特別檢查目前正在研究的SPR-11540 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.