2012-08-07 65 views
1

我明白多個對象,使用Spring的(3.1)建於CacheManager中使用的Ehcache實現,也有一定的侷限性在代理模式下(默認設置)時,按這個帖子:的Ehcache:@CacheEvict上使用批註

Spring 3.1 @Cacheable - method still executed

來考慮一下,我有:

@CacheEvict(value = "tacos", key = "#tacoId", beforeInvocation = true) 
removeTaco(String tacoId) { 
    // Code to remove taco 
} 

removeTacos(Set<String> tacoIds) { 
    for (String tacoId : tacoIds) { 
     removeTaco(tacoId); 
    } 
} 

在這個倉庫方法,調用removeTacos(tacoIds)實際上並不會因爲從上述限制的緩存集中退出任何東西。我的解決方法是,在上面的服務層上,如果我想要刪除多個玉米餅,我會遍歷每個taco Id並將其傳遞到removeTaco(),並且從不使用removeTacos()但是,我不會使用removeTacos()想知道是否有另一種方法來實現這一點。

1)是否有一個SpEL表達式可以傳遞給關鍵字,告訴EhCache過期Set中的每個ID?

e.g. @CacheEvict(value = "tacos", key = "#ids.?[*]") // I know this isn't valid, just can't find the expression. 

或者有沒有一種方法可以讓removeTacos()調用removeTaco並實際過期Cached對象?

回答

1

AFAIK @CacheEvict僅支持刪除單個條目(按鍵)或給定緩存中的所有條目,因此無法立即刪除多個條目。如果你想放置,更新或從緩存中刪除多個對象(使用註釋),你可以切換到memcached看看我的項目Simple Spring Memcached (SSM)

自調用不通過代理,所以解決方案之一是切換到其他模式而不是代理。另一種解決方案(我不推薦它)可能會繼續引用服務中的服務(作爲自動編寫的字段)並使用它來調用removeTaco。

幾個月前,我在我的一個項目中遇到過類似的問題。它沒有使用Spring Cache,但SSM也需要代理。爲了使它工作,我將緩存(註釋)從服務移動到DAO(存儲庫)層。它解決了自調用問題。

2

你可以做兩件事情

@CacheEvict(value = "tacos", allEntries = true) 
removeTacos(Set<String> tacoIds) 

這是不那麼糟糕的,如果玉米餅是通過調用服務中讀取比他們刪除

OR

removeTacos(Set<String> tacoIds) { 
    for (String tacoId : tacoIds) { 
     getTacoService().removeTaco(tacoId); 
    } 
} 

多很多(代理)你調用緩存驅逐。

3

的@Caching註釋可用於相同類型的諸如@CacheEvict或@CachePut的多個註釋結合,這是來自Spring文檔的例子

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value="secondary", key="#p0") }) 
public Book importBooks(String deposit, Date date)