2007年8月21日 星期二

Session Level cache

Hibernate 的 session 物件有一種 cache 機制, 可維護一份您存取資料後的 instance.
因為存取資料庫的連線, 需要不小的開銷. 該機制將存取 persistence object 的結果讀進記憶體(利用一份map物件來維護), 若在 session 結束後, 有相同的SQL操作, 則 cache 機制可以直接將物件回傳, 不用再執行額外的資料庫連線動作; 而這種存活於 session 內的 cache 機制, 又稱為 session Level cache.

用一簡例說明:

....
session.beginTransaction();

Person aPerson = (Person) session.load(Person.class, personId);
aPerson.getAge();

Person aPerson2 = (Person) session.load(Person.class, personId);
aPerson2.getAge();

session.getTransaction().commit();
session.close();
....

您可以觀察 console 內SQL的執行:
Hibernate: select person0_.PERSON_ID as
PERSON1_2_0_, person0_.age as age2_0_, person0_.firstname as
firstname2_0_, person0_.lastname as lastname2_0_ from PERSON person0_
where person0_.PERSON_ID=?
我們可以發現, 雖然 session.load() 呼叫了兩次, 但由於 cache 機制,
會直接回傳記憶體中的物件給 aPerson2 存取, 如此便減少了一次資料庫的連線成本

但有時存取過於頻繁, cache 內有太多的物件有可能會導致 OutOfMemory,
若您想釋放 cache 中的記憶體, 可以使用 session.clear(), session.evict(object),
另外 session.close() 也會結束該段 cache.

以上例而言:
...
Person aPerson = (Person) session.load(Person.class, personId);
aPerson.getAge();

session.evict(aPerson);
//session.clear()

Person aPerson2 = (Person) session.load(Person.class, personId);
aPerson2.getAge();
...
您會發現 console 會執行兩段SQL指令, 因為 session 中的 cache 已被清除了,session.load()
找不到對應的資料, 就會再重起一段資料連線.

Reference:
Hibernate Gossip: 簡介快取(Session Level)
Reference Documentation

0 意見: