【HIBERNATE框架开发之九】HIBERNATE 性能优化笔记!(遍历、一级/二级/查询/缓存、乐观悲观锁等优化算法)...
轉(zhuǎn)載自【黑米GameDev街區(qū)】 原文鏈接:?http://www.himigame.com/hibernate/825.html
1. ? 循環(huán)分頁(yè)或者循環(huán)進(jìn)行部分讀取處理數(shù)據(jù)的時(shí)候,使用 session.clear() ;
?
2. ? ?對(duì)應(yīng)1+N(N+1)問題使用如下解決方式:
1): 使用createCriteria進(jìn)行查詢(join fetch)
2):HQL -> join fetch
3):?使用@fetch設(shè)置LAZY
4):在@Entity下使用注解@BatchSize(size=5)
@BatchSize ?指定每次 讀 取數(shù)據(jù)的數(shù)量
?
3. List 與 iterate 進(jìn)行遍歷取出數(shù)據(jù)庫(kù)數(shù)據(jù)的list();
區(qū)別1)List 直接取出對(duì)象 ? ? ??iterate先會(huì)取出組件,需要使用才會(huì)使用
?
區(qū)別2)同一個(gè)session中每次執(zhí)行l(wèi)ist()取出數(shù)據(jù)時(shí)都會(huì)發(fā)送SQL語(yǔ)句,但是iterate只會(huì)發(fā)出一條,默認(rèn)會(huì)去session緩存去找;
?
4. 緩存,session級(jí)別的緩存稱為一級(jí)緩存,每個(gè)session都有獨(dú)立的一級(jí)緩存,例如多個(gè)線程同時(shí)取同一個(gè)對(duì)象數(shù)據(jù);
解決方案:建立一個(gè)共用的總緩存(總緩存)二級(jí)緩存,如果找不到然后再到各自的session一級(jí)混村中尋找;具體操作如下:首先看緩存策略,
type : 其中memory支持緩存內(nèi)存中,disk支持緩存存放硬盤中;
Cluster Safe :是否支持使用在集群環(huán)境;
Query Cache Supported:是否支持查詢緩存(3級(jí)緩存)
假設(shè)使用EhCacheProvider二級(jí)緩存:
1)修改hibernate.cfg.xml配置文件:
| 1 2 | <property name="cache.use_second_level_cache">true</property> ????<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property> |
2) 在/hibernate-distribution-3.3.2.GA/project/etc/ehcache.xml 配置文件拷貝到項(xiàng)目中;
在ehcache.xml中默認(rèn)如下設(shè)置:
| 1 | ?????<diskStore path="java.io.tmpdir"/> |
| 1 2 3 4 5 6 7 | ???? <defaultCache ????????maxElementsInMemory="10000" ????????eternal="false" ????????timeToIdleSeconds="120" ????????timeToLiveSeconds="1200" ????????overflowToDisk="true" ????????/> |
maxElementsInMemory:在內(nèi)存中最多緩存的對(duì)象數(shù)量
eternal: 緩存內(nèi)存對(duì)象是否永久保存不刪除
timeToIdleSeconds: ?當(dāng)timeToIdleSeconds 周期時(shí)間沒有被使用過,自動(dòng)清除掉;(秒)
timeToLiveSeconds: 緩存對(duì)象的生存時(shí)間(秒)后自動(dòng)清楚;
overflowToDisk:溢出的時(shí)候是否放置在硬盤上
diskStore ?path:默認(rèn)臨時(shí)存放硬盤緩存的路徑
注意:<cache name=”sampleCache1″ ? ?/> 可以自定義cache名,不自定義不指定默認(rèn)是用 <defauleCache ? ….. />
3)將類使用二級(jí)緩存,直接在@Entity下使用注解 ???@Cache ?其設(shè)置如下:
常用的READ_ONLY (只讀),?READ_WRITE(讀寫)
其中@Cache(region=””) 使用自定義ehcache.xml的自定義緩存策略設(shè)置 ~
4)加入ehcache的jar包,路徑如下:/hibernate-distribution-3.3.2.GA/lib/optional/ehcache/ehcache.jar
加入?commons-logging.jar包
? ? ? ? ? ? ?1. ? ?放入二級(jí)緩存如下規(guī)則:
? ? ? ? ? ? ? ? ? ?a) ? 經(jīng)常訪問 ?b) 不經(jīng)常改動(dòng)(改動(dòng)不大) c) 數(shù)據(jù)不是很大?例如用戶權(quán)限;
2. ? ? load 默認(rèn)使用二級(jí)緩存,iterate 默認(rèn)使用二級(jí)緩存
3. list 默認(rèn)往二級(jí)緩存加數(shù)據(jù),list查詢的使用不使用緩存
4. 如果要 query 查詢語(yǔ)句使用二級(jí)緩存,需要打開查詢緩存(同樣的重復(fù)的查詢!)
1) hibernate.cfg.xml配置文件加入配置:
<property name=”cache.use_query_cache”>true</property>
2) 使用Query的setCachable(true) 方法指明使用二級(jí)緩存 ;
?
5. ? ?緩存算法:LRU 、 LFU 、 FIFO
LRU: 最近最少被使用的; (時(shí)間)
LFU: 使用率比較少的;(次數(shù))
FIFO:按照數(shù)據(jù)從0開始拿走(堆棧)
設(shè)置方法:在ehcache.xml繼續(xù)設(shè)置一個(gè)參數(shù): memoryStoreEvictionPolicy=”LRU”
?
6. 事務(wù)隔離機(jī)制(為了避免事務(wù)并發(fā)出現(xiàn)的問題)
1. read-uncommitted : 能讀取沒有提交的數(shù)據(jù); 【會(huì)出現(xiàn)臟讀等問題,一般不設(shè)置此種】
2. read-committed : ?只有提交后才讀;Hibernate建議使用!【能解決臟讀但會(huì)出現(xiàn)不可重復(fù)讀和幻讀問題(手動(dòng)解決)】
3. repeatable read : ? ? ?加鎖;(MySQL默認(rèn)使用?repeatable read?)
4. serializable : ? 序列化,解決任何問題,但是效率最低;
MySQL?支持這四種事務(wù)隔離機(jī)制;?事務(wù)隔離級(jí)別越高效率越慢~
使用 select @@tx_isolation; ?查詢事務(wù)隔離機(jī)制;
? ? ?設(shè)置隔離機(jī)制:?set session tx_isolation=’xxx’; ?
?
Hibernate解決并發(fā)事務(wù)方案:使用Hibernate悲觀鎖和樂觀鎖進(jìn)行設(shè)置;
1)事務(wù)機(jī)制的值為1,2,4,8 (ps. 二進(jìn)制為0001 ,0010,0100,1000 這樣算法效率高)
1.a)使用悲觀鎖:(依賴于數(shù)據(jù)庫(kù)的鎖 解決 repeatable read問題)
在讀取load數(shù)據(jù)的時(shí)候,加入第三個(gè)參數(shù)::
session.load(xxx.class, 1,LockMode.xxx);
LockMode的值如下:
一般只設(shè)置LockMode.UPGRADE
原因:
NONE: 無鎖的機(jī)制,Transaction結(jié)束時(shí)切換到此模式;
READ :在查詢的時(shí)候 hibernate會(huì)自動(dòng)獲取鎖;
write ,insert, update hibernate 會(huì)自動(dòng)獲取鎖;
以上 3種鎖的模式是hibernate內(nèi)部使用的;
UPGRADE—NOWAIT ->是oracle數(shù)據(jù)庫(kù) 支持的鎖;
?
? ? ?1.b)使用樂觀鎖:(程序內(nèi)使用字段version進(jìn)行加鎖,與數(shù)據(jù)庫(kù)沒有關(guān)系)
可以定義一個(gè)version屬性,然后在getVersion上使用注解 @Version
注意:當(dāng)并發(fā)的時(shí)候會(huì)報(bào)錯(cuò),那么找個(gè)錯(cuò)誤交給我們自己來處理; ?
? ? ? ?悲觀與樂觀:悲觀一開始就進(jìn)行加鎖,不論是否有其他事務(wù)來同時(shí)并發(fā);但是樂觀鎖則不進(jìn)行直接加鎖,而是等待更新時(shí)候進(jìn)行檢查對(duì)比下,如果與去之前version不一致那么更新下即可;樂觀鎖效率高;
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖
總結(jié)
以上是生活随笔為你收集整理的【HIBERNATE框架开发之九】HIBERNATE 性能优化笔记!(遍历、一级/二级/查询/缓存、乐观悲观锁等优化算法)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Django Sqlite3 数据库向M
- 下一篇: Nancy之Forms验证