2012-07-31 90 views
1


在這個問題上,我一直在撞牆撞牆。休眠Infinispan實體/查詢緩存

我們正試圖使用​​Infinispan實現Hibernate的二級緩存。該應用程序在JBoss AS 6上運行,並使用JTA事務。

在我們的persistence.xml我們:

... 
<!-- JTA configurations --> 
<property name="hibernate.transaction.manager_lookup_class" value="org.hibernate.transaction.JBossTransactionManagerLookup" /> 
<property name="current_session_context_class" value="jta" /> 

<!-- Infinispan configurations --> 
<property name="hibernate.cache.use_second_level_cache" value="true" /> 
<property name="hibernate.cache.use_query_cache" value="true" /> 

<property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.infinispan.InfinispanRegionFactory"/> 
<property name="hibernate.cache.infinispan.cachemanager" value="java:CacheManager/entity"/> 
... 

定義here:

在我們理解這是種緩存,我們需要爲了做到以下幾點:

使用案例一: 我們在數據庫上有記錄,它將保存參考數據。這些數據不會長時間改變(我們希望:))。

我們希望緩存這些記錄,因爲它們很可能會被查詢。而當用戶查詢這些數據時,不需要去數據庫,因爲它應該被緩存。

對於這種情況,緩存類型是查詢緩存還是實體緩存?作爲查詢總是相同的,我理解它的查詢緩存作爲查詢應始終返回相同的結果。

我的查詢:

List<MyEntity> list = session.createCriteria(MyEntity.class) 
     .add(Restrictions.eq("id", 1)) 
     .setCacheable(true) 
     .list(); 

使用案例二: 用戶得到從數據庫中的特定記錄,他可能會對其進行更新。我們希望將此實體(或實體列表)保存在用戶的會話(登錄會話)緩存中,因此如果他在客戶端上更新了此實體,我們不需要在更新之前進行選擇。 在這種情況下,因爲我們正在保存特定的實體,所以它被認爲是實體緩存,對吧?如果我們要存儲

爲此,我們正在使用:

@Cacheable (true) 
@Cache(usage = CacheConcurrencyStrategy.TRANSACTIONAL) 
public class MyEntity implements Serializable 
{ 
... 
} 

上午我做正確的這些假設?如果不是,這裏有什麼方法?我覺得我正在做一個很大的混亂。

回答

1

第二級(實體)緩存基於id作爲關鍵字(使其更簡單)。因此,每當參考數據在其他實體中被「引用」時,實體管理器在去DB之前首先檢查它是否存在於緩存中。

查詢緩存是查詢結果(ids)實體的緩存。然後根據ID檢索相應的實體(最好從實體緩存中...),因此您需要將實體緩存在二級緩存中才能有用。

對於您的第一個用例,引用數據:您應該將該實體標註爲可緩存並使用只讀策略。實體管理器將在加載時將引用數據放入引用實體中,或者使用find(clazz,id)從第二級緩存中獲取引用數據。

情況2有點棘手。沒有「會話」作用域緩存(如果需要將中間結果綁定到用戶會話,則需要通過SFSB或任何上級會話機制來管理它自己)。如果你讓實體可以緩存,它將被緩存給服務器上的每個用戶,實體管理器上下文與用戶沒有直接的聯繫。

如果要防止在更新之前進行選擇,則應該通過擴展持久性上下文阻止實體達到非託管狀態(以防止合併)。如果實體通常可以由多個用戶更新,則緩存可能會降低性能,因爲管理一致性需要花費更多時間。

如果您遇到性能問題,那麼您應該首先查看相關的實體獲取和傳播註釋,如果它們太大,您向數據庫發出請求或/和更新太多數據。

+0

我仍然試圖吸收你所有的答案。我還有一個問題。對於我的第一個用例,如果我將另一個引用數據對象(記錄)添加到數據庫(使用相同的應用程序)會發生什麼?緩存是否知道查詢的結果已更改,下一次進行選擇時,它會轉到數據庫嗎? – 2012-07-31 17:05:56

+0

我不知道它是否會在它持續存在時將其放入緩存中。可能它會做出選擇,因爲觸發器可能會導致數據更改。任何方式最多隻能選擇一個,然後放入緩存中。 – Kazaag 2012-07-31 20:10:20

+0

你可以在這篇文章中找到更多細節:http://www.javalobby.org/java/forums/t48846.html – Kazaag 2012-07-31 20:10:52