通過以上的介紹可以看出hibernate主要從以下幾個方面來優化查詢性能
降低訪問數據庫的頻率減少select語句的數目實現手段有使用迫切左外連接或迫切內連接對延遲檢索或立即檢索設置批量檢索數目使用查詢緩存
避免加載多余的應用程序不需要訪問的數據實現手段有使用延遲加載策略使用集合過濾
避免報表查詢數據占用緩存實現手段為利用投影查詢功能查詢出實體的部分屬性
減少select語句中的字段從而降低訪問數據庫的數據量實現手段為利用Query的iterate()方法
Query的iterate()方法首先檢索ID字段然後根據ID字段到hibernate的第一級緩存以及第二級緩存中查找匹配的Customer對象如果存在就直接把它加入到查詢結果集中否則就執行額外的select語句根據ID字段到數據庫中檢索該對象
Query query = sessioncreateQuery(from Customer where age<);
Iterator result = erate();
對於經常使用的查詢語句如果啟用了查詢緩存當第一次執行查詢語句時hibernate會把查詢結果存放在第二級緩存中以後再次執行該查詢語句時只需從緩存中獲得查詢結果從而提高查詢性能如果查詢結果中包含實體第二級緩存只會存放實體的OID而對於投影查詢第二級緩存會存放所有的數據值
查詢緩存適用於以下場合在應用程序運行時經常使用的查詢語句很少對與查詢語句關聯的數據庫數據進行插入刪除更新操作
對查詢語句啟用查詢緩存的步驟如下
配置第二級緩存
在hibernate的配置文件中設置查詢緩存屬性hibernatecacheuse_query_cache=true
即使設置了緩存在執行查詢語句時仍然不會啟用查詢緩存只有在調用querysetCacheable()後才啟用緩存
Query query = sessioncreateQuery(from Customer c where cage > :age);
querysetInteger(age age):
querysetCacheable(true);
如果希望更加精粒度地控制查詢緩存可以設置緩存區域querysetCacheRegion(customerQueries);
hibernate提供了種和查詢相關的緩存區域
默認的查詢緩存區域netsfhibernatecacheStandardQueryCache
用戶自定義的查詢緩存區域如customerQueries
時間戳緩存區域netsfhibernatecacheUpdateTimestampCache
默認的查詢緩存區域以及用戶自定義的查詢緩存區域都用於存放查詢結果而時間戳緩存區域存放了對於查詢結果相關的表進行插入更新刪除操作的時間戳hibernate通過時間戳緩存區域來判斷被緩存的查詢結果是否過期當應用進程對數據庫的相關數據做了修改hibernate會自動刷新緩存的查詢結果但是如果其它應用進程對數據庫的相關數據做了修改hibernate無法監測到這一變化此時必須由應用程序負責監測這一變化(如通過發送和接收事件或消息機制)然後手工刷新查詢結果
QuerysetForceCacheRefresh(true)方法允許手工刷新查詢結果它使得hibernate丟棄查詢緩存區域中己有的查詢結果重新到數據庫中查詢數據再把查詢結果存放在查詢緩存區域中
一個session可以和多個事務對應
Transaction trans = sessionbeginTransaction();
//數據庫操作
mit();//提交第一個事務
sessiondisconnect();//釋放數據庫連接
//執行一些耗時的操作這段操作不屬於任何事務
sessionreconnect();//重新獲取數據庫連接
Transaction trans = sessionbeginTransaction();//開始第二個事務
//數據庫操作
mit();//提交第二個事務
注意如果在執行session的一個事務時出現了異常就必須立即關閉這個session不能再利用這個session來執行其它的事務
許多數據庫系統都有自動管理鎖的功能它們能根據事務執行的SQL語句自動在保證事務間的隔離性與保證事務間的並發性之間做出權衡然後自動為數據庫資源加上適當的鎖在運行期間還會自動升級鎖的類型以優化系統的性能
對於普通的並發性事務通過系統的自動鎖定管理機制基本可以保證事務之間的隔離性但如果對數據安全數據庫完整性和一致性有特殊要求也可以由事務本身來控制對數據資源的鎖定和解鎖
數據庫系統能夠鎖定的資源包括數據庫表區域頁面鍵值(指帶有索引的行數據)行(即表中的單行數據)在數據庫系統中一般都支持鎖升級以提高性能
按照封鎖程序鎖可以分為共享鎖獨占鎖更新鎖
共享鎖用於讀數據操作它是非獨占的允許其它事務同時讀取其鎖定的資源但不允許其它事務更新它
獨占鎖也稱排它鎖適用於修改數據的場合它所銷定的資源其它事務不能讀取也不能修改
更新鎖在更新操作的初始化階段用來鎖定可能要被修改的資源這可以避免使用共享鎖造成的死鎖現象
許多的數據庫系統能夠自動定期搜索和處理死鎖問題當檢測到鎖定請求環時系統將結束死鎖優先級最低的事務並且撤銷該事務
應用程序中可以采用下面的一些方法盡量避免死鎖
合理安排表訪問順序
使用短事務
如果對數據的一致性要求不高可以允許髒讀髒讀不需要對數據資源加鎖可以避免沖突
如果可能的話錯開多個事務訪問相同數據資源的時間以防止鎖沖突
使用盡可能低的事務隔離級別
為了實現短事務在應用程序中可以考慮使用以下策略
如果可能的話嘗試把大的事務分解為多個小的事務然後分別執行這保證每個小事務都很快完成不會對數據資源鎖定很長時間
應該在處理事務之前就准備好用戶必須提供的數據不應該在執行事務過程中停下來長時間等待輸入數據
數據庫系統提供了四種事務隔離級別供用戶選擇
Serializable串行化
Repeatable Read可重復讀
Read Commited讀己提交數據
Read Uncommited讀未提交數據
隔離級別越高越能保證數據的完整性和一致性但是對並發性能的影響也越大對於多數應用程序可以優先把數據庫系統的隔離級別設為ReadCommited它能夠避免髒讀而且具有較好的並發性能盡管它會導致不可重復讀虛讀和第二類丟失更新這些並發問題在可能出現這類問題的個別場合可以由應用程序采用悲觀鎖或樂觀鎖來控制
JDBC數據庫連接使用數據庫系統默認的隔離級別在hibernate的配置文件中可以顯式地設置隔離級別(nnectionisolation=)每一種隔離級別都對應一個整數
Read Uncommitted
Read Committed
Repeatable Read
Serializable
在受管理的環境中如果hibernate使用的是數據庫連接來自於應用服務器提供的數據源hibernate不會修改這些連接的事務隔離級別在這種情況下應該通過修改應用服務器的數據源配置來修改隔離級別
悲觀鎖指在應用程序中顯式地為數據資源加鎖先鎖定資源再進行操作盡管悲觀鎖能夠防止丟失更新和不可重復讀這類並發問題但是它會影響並發性能因此應該很謹慎地使用悲觀鎖
樂觀鎖完全依靠數據庫的隔離級別來自動管理鎖的工作應用程序采用版本控制手段來避免可能出現的並發問題
悲觀鎖有兩種實現方式在應用程序中顯式指定采用數據庫系統的獨占鎖來鎖定數據資源在數據庫表中增加一個表明記錄狀態的LOCK字段當它取值為Y時表示該記錄己經被某個事務鎖定如果為N表明該記錄處於空閒狀態事務可以訪問它
以下select語句指定采用獨占鎖來鎖定查詢的記錄select for update;執行該查詢語句的事務持有這把鎖直到事務結束才會釋放鎖
hibernate可以采用如下方式聲明使用悲觀鎖Account account = (Account)sessionget(Accountclass LockModeUPGRADE);
netsfhibernateLockMode類表示鎖模式它的取值如下
LockModeNONE默認值先查緩存緩存沒有再去數據庫中查
LockModeREAD總是查詢數據庫如果映射文件設置了版本元素就執行版本比較主要用於對一個游離對象進行版本檢查
LockModeUPGRADE總是查詢數據庫如果映射文件設置了版本元素就執行版本比較如果數據庫支持悲觀鎖就執行 for update否則執行普通查詢
LockModeUPGRADE_NOWAIT和UPGRADE功能一樣此外對oracle數據庫執行 for update nowait; nowait表明如果不能立即獲得悲觀鎖就拋出異常
LockModeWRITE當hibernate向數據庫保存或更新一個對象時會自動使用這種模式它僅供hibernate內部使用應用程序中不應該使用它
如果數據庫不支持select for update語句也可以由應用程序來實現悲觀鎖這需要要表中增加一個鎖字段lock
hibernate映射文件中的<version>和<timestamp>元素都具有版本控制功能<version>利用一個遞增的整數來跟蹤數據庫表中記錄的版本<timestamp>用時間戳來跟蹤數據庫表中記錄的版本
version的用法如下
配置文件中<version name=version column=VERSION/>必須緊跟在<id>元素的後面數據庫中的version(int)字段與version屬性映射
應用程序無需為JavaBean的version屬性顯示賦值在持久化JavaBean對象時hibernate會自動為它賦初始值在更新數據時hibernate會更新自動version屬性update ACCOUNTS set NAME=TomBALANCE=VERSION= where ID= and VERSION=;
如果在此過程中有其它程序操作過此記錄那麼它的version就會有更新再次執行update語句時會找不到匹配的記錄此時hibernate會拋出StaleObjectStateException在應用程序中應該處理這種異常處理方法有兩種
自動撤消事務通知用戶信息己被其它事務修改需要重新開始事務
通知用戶信息己被其它事務修改顯示最新數據由用戶決定如果繼續
只有當hibernate通過update語句更新一個對象時才會修改它的version屬性對於存在關聯關系的對象只更新發生變化的對象對沒有發生變化的關聯對象是不會更新的也就是說version不具有級聯特性
timestamp用法如下
配置文件和表中各加一個屬性(表中是timestamp類型)<timestamp name=lastUpdatedTime column=LAST_UPDATED_TIME />必須緊跟在<id>元素的後面
當持久化一個JavaBean對象時hibernate會自動用當前的系統時間為lastUpdatedTime屬性賦值更新時也會用系統時間來更新此字段理論上<version>元素比<timestamp>更安全一些因為<timestamp>只能精確到秒不能處理毫秒內的同步
因此建議使用基於整數的<version>元素
對游離對象進行版本檢查如果不一致會拋出StaleObjectStateException()
Transaction trans = sessionbeginTransaction();
sessionlock(account LockModeREAD);//僅僅執行版本檢查(與數據庫中的最新數據進行比較)而不會保存數據庫
mit();
如果數據庫中不包含代表版本或時間戳的字段hibernate提供了其它方法實現樂觀鎖把<class>元素的optimisticlock屬性設為all把<class>元素的optimisticlock屬性設為all或dirty必須同時把dynamicupdate屬性設為true
optimisticlock=true時hibernate更新時會在where子句中包含JavaBean對象被加載時的所有屬性
optimisticlock=dirty時hibernate更新時會在where子句中僅包含被更新過的屬性
盡管這種方法也能實現樂觀鎖但是這種方法速度很慢而且只適用於在同一個session中加載了該對象然後又在同一個session中更新了此對象的場合如果在不同的session中會導致第二個session無法知道JavaBean對象被第一個session加載時所有屬性的初始值因此不能在update語句的where子句中包含JavaBean對象的屬性的初始值因此執行以下update語句update ACCOUNTS set NAME=tomBALANCE= where ID=;這會導致當前事務覆蓋其它事務對這條記錄己做的更新
hibernate的二級緩存本身的實現很復雜必須實現並發訪問策略以及數據過期策略SessionFactory的外置緩存是一個可配置的緩存插件在默認情況下不會啟用
二級緩存進程范圍或群集范圍會出現並發問題對二級緩存可以設定以下四種類型的並發訪問策略每一種策略對應一種事務隔離級別
事務型僅僅在受管理環境中適用它提供Repeatable Read事務隔離級別對於經常讀但是很少寫的數據可以采用這種隔離級別因為它可以防止髒讀和不可重復讀這類並發問題
讀寫型提供Read Committed事務隔離級別僅僅在非群集的環境中適用對於經常讀但是很少寫的數據可以采用這種隔離類型因為它可以防止髒讀這類並發問題
非嚴格讀寫型不保證緩存與數據庫中數據的一致性如果存在兩個事務同時訪問緩存中相同數據的可能必須為該數據配置一個很短的數據過期時間從而盡量避免髒讀對於極少被修改並且允許髒讀的數據可以采用這種並發訪問策略
只讀型對於從來不會寫的數據可以使用這種並發訪問策略
事務型策略的隔離級別最高只讀型的最低事務隔離級別越高並發性能越低如果二級緩存中存放中的數據會經常被事務修改就不得不提高緩存的事務隔離級別但這又會降低並發性能因此只有符合以下條件的數據才適合於存放到二級緩存中
很少被修改不是很重要的數據允許偶爾出現並發問題不會被並發訪問的數據參考數據
以下數據不適合於存放到二級緩存中
經常被修改的數據財務數據絕對不允許出現並發問題與其它應用共享的數據
hibernate還為查詢結果提供了一個查詢緩存它依賴於二級緩存
Session為應用程序提供了兩個管理一緩存的方法
evict()從緩存中清除參數指定的持久化對象如果在映射文件關聯關系的cascade為all或alldeleteorphan時會級聯清除它適用於不希望session繼續按照該對象的狀態變化來同步更新數據庫在批量更新或指量刪除的場合當更新或刪除一個對象後及時釋放該對象占用的內存值得注意的是批量更新或刪除的最佳方式是直接通過JDBC API執行相關的SQL語句或者調用相關的存儲過程
clear()清空緩存中所有持久化對象
在多數情況下不提倡通過evict()和clear()方法來管理一級緩存因為它們並不能顯著地提高應用的性能管理一級緩存的最有效的方法是采用合理的檢索策略和檢索方式如通過延遲加載集合過濾投影查詢等手段來節省內存開銷
hibernate中直接通過JDBC API來執行更新或刪除操作的方法如下
Transaction trans = sessionbeginTransaction();
Connection conn = nnection();
PreparedStatement statement = connprepareStatement(update ACCOUNTS set AGE=AGE+ where AGE>);
statementexecuteUpdate();
mit();
如果底層數據庫支持存儲過程也可以直接調用存儲過程來執行指量更新
Transaction trans = sessionbeginTransaction();
Connection conn = nnection();
CallableStatement statement = connprepareCall({call batchUpdateCustomer(?)});
statementsetInt( );//把第個參數的值設為
statementexecuteUpdate();
mit();
hibernate中session的各種重載的update()方法一次都只能更新一個對象而delete()方法有些重載形式允許以HQL語句作為參數如
sessiondelete(from Customer c where cage>);
但是它並不是執行一條delete語句而是把符合條件的數據先查找出來再一個個地執行delete操作
hibernate的二級緩存允許選用以下類型的緩存插件
EHCache可作為進程范圍內的緩存存放數據的物理介質可以是內存或硬盤對hibernate的查詢緩存提供了支持
OpenSymphony OSCache可作為進程范圍內的緩存存放數據的物理介質可以是內存或硬盤提供了豐富的緩存數據過期策略對hibernate的查詢緩存提供了支持
SwarmCache可作為群集范圍內的緩存但不支持hibernate的查詢緩存
JBossCache可作為群集范圍內的緩存支持事務型並發訪問策略對hibernate的查詢緩存提供了支持
下表列出了以上四種類型的緩存插件支持的並發訪問策略
以面的四種緩存插件都是由第三方提供的EHCache來自於hibernate開放源代碼組織的另一個項目JBossCache由JBoss開放源代碼組織提供為了把這些緩存插件集成到hibernate中hibernate提供了netsfhibernatecacheCacheProvider接口它是緩存插件與hibernate之間的適配器hibernate為以上緩存插件分別提供了內置的CacheProvider實現
netsfhibernatecacheEhCacheProvider
netsfhibernatecacheOSCacheProvider
netsfhibernatecacheSwarmCacheProvider
netsfhibernatecacheTreeCacheProviderJBossCache插件適配器
配置進程范圍內的二級緩存主要包含以下步驟
選擇需要使用二級緩存的持久化類設置它的命名緩存的並發訪問策略hibernate既允許在分散的各個映射文件中為持久化類設置二級緩存還允許在hibernate的配置文件hibernatecfgxml中集中設置二級緩存後一種方式更有利於和緩存相關的配置代碼的維護示例如下
<hibernateconfiguration>
<sessionfactory>
<property >
<! 設置JBossCache適配器 >
<property name=cacheprovider_class>netsfhibernatecacheTreeCacheProvider</property>
<property name=cacheuse_minimal_puts>true</property>
<mapping />
<! 設置Category類的二級緩存的並發訪問策略 >
<classcache class=mypackCategory usage=transaction />
<! 設置Category類的items集合的二級緩存的並發訪問策略 >
<collectioncache collection=ems usage=transactional />
<! 設置Item類的二級緩存的並發訪問策略 >
<classcache class=mypackItem usage=transactional />
</sessionfactory>
</hibernateconfiguration>
cacheuse_minimal_puts屬性為true表示hibernate會先檢查對象是否己經存在於緩存中只有當對象不在緩存中才會向緩存加入該對象的散裝數據默認為false對於群集范圍的緩存如果讀緩存的系統開銷比寫緩存的系統開銷小可以將此屬性設為true從而提高訪問緩存的性能而對於進程范圍內的緩存此屬性應該取默認值false
選擇合適的緩存插件每種插件都有自帶的配置文件因此需要手工編輯該配置文件EHCache的配置文件為ehcachexml而JBossCache的配置文件為treecachexml在配置文件中需要為每個命名緩存設置數據過期策略
hibernate允許在類和集合的粒度上設置二級緩存在映射文件中<class>和<set>元素都有一個<cache>子元素這個子元素用來配置二級緩存例如以下代碼把Category實例放入二級緩存中采用讀寫並發訪問策略
<class name=mypackCategory talbe=CATEGORIES>
<cache usage=readwrite/>
<id >
</id>
</class>
每當應用程序從其它對象導航到Category對象或者從數據庫中加載Category對象時hibernate就會把這個對象放到第二級緩存中<class>元素的<cache>子元素表明hibernate會緩存Category對象的簡單屬性的值但是它並不會同時緩存Category對象的集合屬性如果希望緩存集合屬性中的元素必須在<set>元素中加入<cache>子元素
<set name=items inverse=true lazy=true>
<cache usage=readwrite />
<key >
</set>
當應用程序調用categorygetItems(erate()方法時hibernate會把item集合中的元素存放到緩存中此時hibernate僅僅把與Category關聯的Item對象的OID存放到緩存中如果希望把整個Item對象的散裝數據存入緩存應該在Itemhbmxml文件的<class>元素中加入<cache>子元素
EHCache緩存插件是理想的進程范圍內的緩存實現如果使用這種緩存插件需要在hibernate的hibernateproperties配置文件中指定EhCacheProvider適配器代碼如下
hibernatecacheprovider=netsfhibernatecacheEhCacheProvider
EHCache緩存有自己的配置文件名為ehcachexml這個文件必須存放於應用的classpath中下面是一個樣例
<ehcache>
<diskStore path=C:\\temp/>
<defaultCache maxElementsInMemory= eternal=false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk=true/>
<cache name=mypackCategory maxElementsInMemory= eternal=true timeToIdleSeconds= timeToLiveSeconds= overflowToDisk=false/>
<cache name=ems maxElementsInMemory= eternal=false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk=true/>
<cache name=mypackItem maxElementsInMemory= eternal=false timeToIdleSeconds= timeToLiveSeconds= overflowToDisk=true/>
</ehcache>
hibernate軟件包的etc目錄下提供了ehcachexml文件的樣例並且對於它的配置元素做了詳細的說明
ehcachexml目錄下提供了ehcachexml文件的樣例並且對它的配置元素做了詳細的說明
<diskStore>指定一個文件目錄當EHCache把數據寫到硬盤上時將把數據寫到這個文件目錄下
<defaultCache>設定緩存的默認數據過期策略
<cache>設定具體的命名緩存的數據過期策略
在映射文件中對每個需要二級緩存的類和集合都做了單獨的配置與此對應在ehcachexml文件中通過<cache>元素來為每個需要二級緩存的類和集合設定緩存的數據過期策略下面解釋一下<cache>元素的各個屬性的作用
name設置緩存的名字它的取值為類的完整名字或者類的集合的名字如果name屬性為mypackCategory表示Category類的二級緩存如果name屬性為ems表示Category類的items集合的二級緩存
maxInMemory設置基於內存的緩存可存放的對象的最大數目
eternal如果為true表示對象永遠不會過期此時會忽略timeToIdleSeconds和timeToLiveSeconds屬性默認為false
timeToIdleSeconds設定允許對象處於空閒狀態的最長時間以秒為單位當對象從最近一次被訪問後如果處於空閒狀態的時間超過了指定的值這個對象會過期EHCache將把它從緩存中清除只有當eternal屬性為false它才有效值為表示對象可以無限期地處於空閒狀態
timeToLiveSeconds設定對象允許存在於緩存中的最長時間以秒為單位當對象自從被放入緩存中後如果處於緩存中的時間超過了指定的值這個對象就會過期EHCache將把它從緩存中清除只有當eternal屬性為false它才有效值為表示對象可以無限期地處於空閒狀態它的值必須大於或等於timeToIdleSeconds的值才有意義
overflowToDisk如果為true表示當基於內存的緩存中的對象數目達到了maxInMemory界限會把溢出的對象寫到基於硬盤的緩存中
每個命名緩存代表一個緩存區域每個緩存區域有各自的數據過期策略命名緩存機制使得用戶能夠在每個類以及類的每個集合的粒度上設置數據過期策略
EHCache適用於hibernate應用發布在單個機器中的場合
在群集環境下可以用JBossCache作為hibernate的二級緩存它的配置步驟如下
在hibernate配置文件中設置JBossCache適配器並且為需要使用二級緩存的類和集合設置緩存的並發訪問策略
編輯JBossCache自身的配置文件名為treecachexml這個文件必須放在classpath中對於群集環境中的每個節點都必須提供單獨的treecachexml文件假如群集環境中有兩個節點node A和node Bnode A節點的名字為ClusterA下面是node A節點的treecachexml文件的樣例
<?xml version= encoding=UTF?>
<server>
<classpath codebase=/lib archives=jbosscachejarjgroupsjar/>
<! 把TreeCache發布為JBoss的一個JMX服務 >
<mbean code=orgjbosscacheTreeCache name=jbosscache:service=TreeCache>
<depends>jboss:service=Naming</depends>
<depends>jboss:service=TransactionManager</depends>
<! TreeCache運行在群集環境的名為ClusterA的節點上 >
<attribute name=ClusterName>ClusterA</attribute>
<! TreeCache采用同步通信機制 >
<attribute name=CacheMode>REPL_SYNC</attribute>
<attribute name=SyncReplTimeout></attribute>
<attribute name=LockAcquisitionTimeout></attribute>
<attribute name=FetchStateOnStartup>true</attribute>
<! TreeCache采用內置的數據過期策略LRUPolicy >
<attribute name=EvictionPolicyClass>orgjbosscacheevictionLRUPolicy</attribute>
<attribute name=EvictionPolicyConfig>
<config>
<attribute name=wakeUpIntervalSeconds></attribute>
<! Cache wide default >
<region name=/_default_>
<attribute name=maxNodes></attribute>
<attribute name=timeToIdleSeconds></attribute>
</region>
<! 配置Category類的數據過期策略 >
<region name=/mypack/Category>
<attribute name=maxNodes></attribute>
<attribute name=timeToIdleSeconds></attribute>
</region>
<! 配置Category類的items集合的數據過期策略 >
<region name=/mypack/Category/items>
<attribute name=maxNodes></attribute>
<attribute name=timeToIdleSeconds></attribute>
</region>
</config>
</attribute>
<! 配置JGroup >
<attribute name=ClusterConfig>
<config>
<UDP bind_addr= ip_mcast=true loopback=false />
<PING timeout= num_initial_members= up_thread=false down_thread=false />
<FD_SOCK/>
<pbcastNAKACK gc_lag= retransmit_timeout= max_xmit_size= up_thread=false down_thread=false />
<UNICAST timeout= window_size= min_threshold= down_thread=false />
<pbcastSTABLE desired_avg_gossip= up_thread=false down_thread=false />
<FRAG frag_size= down_thread=false up_thread=false />
<pbcastGMS join_timeout= join_retry_timeout= shun=true print_local_addr=true />
<pbcastSTATE_TRANSFER up_thread=true down_thread=true />
</config>
</attribute>
</mbean>
</server>
以上配置文件把JBossCache配置為JBoss的一個JMX服務此外還配置了JGroup它是一個通信庫JBoss為JBossCache提供了幾種實現hibernate采用的是TreeCache實現treecachexml文件夾的開頭幾行是JBoss的JMX服務的發布描述符如果TreeCache不運行在JBoss服務器中這幾行會被忽略
TreeCache采用內置的orgjbosscacheevictionLRUPolicy策略它是一種控制緩存中的數據過期的策略由於當一個對象過期後就會從緩存中清除因此數據過期策略也叫做數據清除策略接下來配置了Category類和它的items集合設置了具體的數據過期策略
最後配置了JGroup它包含一系列通信協議這些通信協議的次序很重要不能隨意修改它們第一個協議為UDP它和一個IP地址綁定這是當前節點的IP地址UDP協議使得該節點支持廣播通信如果節點選用的是微軟的windows平台必須把loopback屬性設為true其它的JGroup屬性很復雜它們主要用於管理群集中節點之間的通信想進一步了解可以參考JBoss網站上的JGroup文檔
可以按照同樣的方式配置node B節點的treecachexml文件只需修改其中UDP協議的IP綁定地址
通過以上配置hibernate將啟用群集范圍內的事務型緩存每當一個新的元素加入到一個節點的緩存中時這個元素就會被復制到其它節點的緩存中如果緩存中的一個元素被更新那麼它就會過期並從緩存中清除
只有在hibernate的配置文件或映射文件中為一個持久化類設置了二級緩存hibernate在加載這個類的實例時才會啟用二級緩存
SessionFactory也提供了evict()方法用於從二級緩存中清除對象的散裝數據如
sessionFactoryevict(Categoryclass );//清除二級緩存中OID為的Category對象
sessionFactoryevict(mypackCategory);//清除二級緩存中所有的Category對象
sessionFactoryevictCollection(ems);//清除二級緩存中Category類的所有對象的items集合
下面是比較hibernate的一級緩存和二級緩存
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28564.html