2011-09-20 42 views
3

我對通過hibernate緩存教程發現的語句有疑問。有關Hibernate緩存機制的一些說明?

語句1: - 第一級緩存始終與會話對象關聯。 Hibernate默認使用這個緩存。

問題1: -
由於這個緩存是在默認情況下保存所有的會話方法,如負荷的結果,得到等慣於這是因爲持有SEESION所有對象的主要內存問題?

問題2: -
我們是否需要啓用這個高速緩存或它的存在,在默認情況下?如果我想要,我可以禁用一級緩存嗎?如果是的話如何?

下面的問題是兩個第一級和第二級緩存

問題3: -
如果我從緩存相同的對象(比如說我加載對象客戶與客戶ID 1兩次在同一會話)從緩存返回的兩個對象都將具有不同於位於緩存中的對象的引用。 對不對?因爲如果我更新客戶對象中的某個字段,直到除非調用save/update方法,它都不應該反映在緩存中。

問題4: -
按我的理解,如果我們試圖從該高速緩存獲得來自ID第二次客戶對象時,它會返回即使它得到了更新之間的老對象。 我們如何確保它從數據庫中讀取更新,否則從緩存中讀取數據?我想我們可以用閱讀類的高速緩存寫入策略一樣的EHCache

Question5: - 在查詢緩存
我讀到這樣一句話:-Updates在查詢的發生非常頻繁。因此,對於查詢緩存,兩個緩存區域是必需的。

用於存儲結果(僅用於緩存標識符值和結果值類型)。 用於存儲最新的更新。

我認爲「查詢中的更新經常發生」是指在這裏我們通常會更改一些參數值,如select * from customer where custid=?因此id將針對不同的客戶ID進行更改。所以查詢緩存將保持每個查詢(連同參數)和每個查詢返回的結果。

對不對?但不知道爲什麼我們需要兩個緩存區域進行查詢緩存?

回答

4

AFAIK
答01:

Hibernate的緩存加載,從而避免不必要的數據庫訪問的對象。避免持久性上下文的最簡單方法是使用StatelessSession。無狀態Hibernate會話沒有髒檢查責任,因此符合您沒有第一級緩存(持久性上下文)的要求。

答02:

  1. 您不必啓用一級緩存

回答03

  1. 如果一個對象在使用其身份的同一個會話中被加載兩次,Hibernate確保無論是否啓用二級緩存,都會返回相同的對象。讓我澄清一下,二級緩存不緩存對象的實例。它維護一個序列化(不完全)的實例版本。 下面的link給出了休眠二級緩存結構的簡要說明。

我很抱歉,但我無法理解「更新客戶對象並且它沒有反映在緩存中」的概念。我希望鏈接能澄清你的問題。如果配置不正確,確實出現了

回答04

  1. 從緩存中獲取過時數據的問題。 如果高速緩存上的到期時間尚未發生,則將獲取狀態數據。驅逐可以使用Session.evict()進行,但是您可能不清楚需要驅逐哪些數據。因此,緩存應始終是優化數據庫訪問的最後一步。 通過重新評估收集關係的關聯和獲取計劃可以實現優化級別的優化,從而避免N + 1選擇問題並同時避免。

    EHCache提供read-write緩存針對未獲得更新的數據的備份 符合交易read committed保護。這是避免dirty reads,但不能幫助repeatable reads

退房的EHCache配置here

答05:查詢緩存

  1. 請查看以下鏈接更好地瞭解會話緩存和查詢緩存
    A. Session Cache
    B. Second Level Cache
    C. Query Cache

  2. Checkout this link它給出了查詢緩存結構的簡單說明。

希望這會有所幫助。

+0

感謝rictionlesspulley這樣一個精心的答覆。我有這些後續查詢。正如你所說:「讓我澄清二級緩存不緩存對象的實例,它維護一個序列化(不完全)的實例版本」「我沒有得到你序列化cahe的意思嗎?關於EH CAche,正如你所說的,我們可以得到讀取提交的事務acroos ression。這就是我需要的。 –

+0

如果你到第二個鏈接的答案05,你將會看到對象是如何存儲在第二級緩存中的,我的意思是序列化版本的緩存對象* NOT THE CACHE ITSELF – frictionlesspulley

+0

關於EHCache的讀寫緩存策略,請務必設置適當的緩存過期時間! – frictionlesspulley