Hibernate脏检查的剖析
介紹
持久性上下文使實(shí)體狀態(tài)轉(zhuǎn)換進(jìn)入隊列,該實(shí)體狀態(tài)轉(zhuǎn)換在刷新后轉(zhuǎn)換為數(shù)據(jù)庫語句。 對于托管實(shí)體,Hibernate可以代表我們自動檢測傳入的更改并安排SQL UPDATE。 這種機(jī)制稱為自動臟檢查 。
默認(rèn)的臟檢查策略
默認(rèn)情況下,Hibernate檢查所有托管實(shí)體屬性。 每次加載實(shí)體時,Hibernate都會復(fù)制所有實(shí)體屬性值。 在刷新時,每個受管實(shí)體屬性都會與加載時快照值匹配:
因此,每個臟檢查的數(shù)量由以下公式給出:
哪里
n =受管理實(shí)體的數(shù)量
p =給定實(shí)體的實(shí)體數(shù)
即使單個實(shí)體的僅一個屬性發(fā)生了變化,Hibernate仍將檢查所有托管實(shí)體。 對于大量的受管實(shí)體,默認(rèn)的臟檢查機(jī)制可能會占用大量CPU和內(nèi)存。 由于初始實(shí)體快照是單獨(dú)保存的,因此持久性上下文所需的內(nèi)存是所有受管實(shí)體通常占用的內(nèi)存的兩倍。
字節(jié)碼檢測
一種更有效的方法是在值更改時標(biāo)記臟屬性。 與原始的深度比較策略類似,優(yōu)良作法是將域模型結(jié)構(gòu)與更改檢測邏輯分離。 自動實(shí)體更改檢測機(jī)制是一個跨領(lǐng)域的問題 ,可以在構(gòu)建時或運(yùn)行時進(jìn)行編織。
實(shí)體類可以附加實(shí)現(xiàn)自動臟檢查機(jī)制的字節(jié)碼級指令。
編織方式
字節(jié)碼增強(qiáng)可以發(fā)生在:
- 構(gòu)建時間編譯休眠實(shí)體之后,構(gòu)建工具(例如ANT , Maven )將在每個已編譯實(shí)體類中插入字節(jié)碼級別的指令。 由于類是在構(gòu)建時增強(qiáng)的,因此此過程不會產(chǎn)生額外的運(yùn)行時損失。 可以針對增強(qiáng)的類版本進(jìn)行測試,以便在構(gòu)建項目之前驗(yàn)證實(shí)際的生產(chǎn)代碼。
- 運(yùn)行時可以使用以下方法完成運(yùn)行時編織:
- Java代理,在實(shí)體類加載時進(jìn)行字節(jié)碼增強(qiáng)
邁向默認(rèn)字節(jié)碼增強(qiáng)臟檢查
Hibernate 3一直通過ANT目標(biāo)提供字節(jié)碼檢測,但是它從未成為主流,大多數(shù)Hibernate項目目前仍在使用默認(rèn)的深度比較方法。
雖然其他JPA提供程序(例如OpenJPA , DataNucleus )一直在支持字節(jié)碼增強(qiáng)方法,但是Hibernate才剛剛開始朝這個方向發(fā)展,提供了更好的構(gòu)建時選項,甚至提供了自定義的臟檢查回調(diào) 。
在我的下一篇文章中,我將向您展示如何使用自己的特定于應(yīng)用程序的策略自定義臟檢查機(jī)制。
翻譯自: https://www.javacodegeeks.com/2014/08/the-anatomy-of-hibernate-dirty-checking.html
總結(jié)
以上是生活随笔為你收集整理的Hibernate脏检查的剖析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Zapier将应用程序与Neo4j集
- 下一篇: 识别JVM –比预期的要复杂