搜尋
首頁後端開發C#.Net教程關於hibernate快取的問題:

關於hibernate快取的問題:

Dec 20, 2016 pm 02:19 PM
hibernate

1.     關於hibernate快取的問題:
1.1.1.        基本的快取原理
Hibernate快取分為二級,而第一級存放於session中稱為一級快取,預設有且無法卸載。
 
第二級是由sessionFactory控制的進程級快取。是全域共享的緩存,凡是會呼叫二級快取的查詢方法 都會從中受益。只有經過正確的配置後二級快取才會發揮作用。同時在進行條件查詢時必須使用對應的方法才能從快取中取得資料。例如Query.iterate()方法、load、get方法等。必須注意的是session.find方法永遠是從資料庫中獲取數據,不會從二級快取中獲取數據,即便其中有其所需的數據也是如此。
 
查詢時使用快取的實現過程為:首先查詢一級快取中是否具有需要的數據,如果沒有,查詢二級緩存,如果二級快取中也沒有,此時再執行查詢資料庫的工作。要注意的是:此3種方式的查詢速度是依序降低的。
1.2.   存在的問題
1.2.1.      一級快取的問題以及使用二級快取的原因
     因為Session的生命期往往很短,而存在於Session內部的第一級最快快取的生命期當然也很短,存在於Session內部的第一級最快的生命期當然也短,所以第一級快取的命中率是很低的。其對系統性能的改善也是很有限的。當然,這個Session內部快取的主要功能是保持Session內部資料狀態同步。並非是hibernate為了大幅提高系統效能所提供的。
為了提高使用hibernate的效能,除了常規的一些需要注意的方法例如:
使用延遲載入、迫切外連接、查詢過濾等以外,還需要配置hibernate的二級快取。其對系統整體性能的改善往往具有立竿見影的效果!
(經過自己先前作專案的經驗,一般會有3~4倍的效能提升)
 
1.2.2.      N+1次查詢的問題
執行條件查詢時,iterate()方法具有著名的「n+ 1」次查詢的問題,也就是說在第一次查詢時iterate方法會執行滿足條件的查詢結果數再加一次(n+1)的查詢。但是此問題只存在於第一次查詢時,在後面執行相同查詢時效能會得到極大的改善。此方法適合查詢資料量較大的業務資料。
但是注意:當資料量特別大時(例如管線資料等)需要針對此持久化物件配置其特定的快取策略,例如設定其存在於快取中的最大記錄數、快取存在的時間等參數,以避免系統將大量的資料同時裝載入記憶體中引起記憶體資源的快速耗盡,反而降低系統的效能! ! !
 
1.3.   使用hibernate二級快取的其他注意事項:
1.3.1.      關於資料的有效性
另外,hibernate會自行維護以確保快取中的資料和資料庫中的真實資料的一致性!無論何時,當你呼叫save()、update()或saveOrUpdate()方法傳遞一個物件時,或使用load()、 get()、list()、iterate() 或scroll()方法取得一個物件時, 該物件都將被加入到Session的內部快取中。 當隨後flush()方法被呼叫時,物件的狀態會和資料庫取得同步。
 
也就是說刪除、更新、增加資料的時候,同時更新快取。當然這也包括二級緩存!
 
只要是呼叫hibernate API執行資料庫相關的工作。 hibernate都會為你自動保證 快取資料的有效性! !
 
但是,如果你使用了JDBC繞過hibernate直接執行對資料庫的操作。此時,Hibernate不會/也不可能自行感知到資料庫被進行的變化改動,也就不能再保證快取中資料的有效性! !
 
這也是所有的ORM產品共同具有的問題。幸運的是,Hibernate為我們揭露了Cache的清除方法,這給了我們一個手動保證資料有效性的機會! !
一級緩存,二級緩存都有相應的清除方法。
 
其中二級快取提供的清除方法為:
按物件class清空快取
               
   

1.3.2.      適合使用的情況
並非所有的情況都適合於使用二級緩存,需要根據具體情況來決定。同時可以針對某一個持久化物件配置其具體的快取策略。
 
適合使用二級快取的情況:
1、資料不會被第三方修改;
 
一般情況下,會被hibernate以外修改的資料最好不要配置二級緩存,以免造成不一致的資料。但如果此資料因為效能的原因需要被緩存,同時又有可能被第3方例如SQL修改,也可以為其配置二級快取。只是此時需要在sql執行修改後手動呼叫cache的清除方法。以確保資料的一致性
 
  2、資料大小在可接收範圍之內;
 
     如果資料表資料量特別龐大,此時不適合於二級快取。原因是快取的資料量過大可能會造成記憶體資源緊張,反而降低效能。
 
如果資料表資料量特別龐大,但是經常使用的往往只是較新的那部分資料。此時,也可為其配置二級快取。但必須單獨配置其持久化類別的快取策略,例如最大快取數、快取過期時間等,將這些參數降低至合理的範圍(太高會造成記憶體資源緊張,太低了快取的意義不大)。
 
  3、數據更新頻率低;
 
     對於數據更新頻率過高的數據,頻繁同步緩存中數據的代價可能和 查詢緩存中的數據從中獲得的好處相當,壞處益處相抵消。此時快取的意義也不大。
 
 
  4、非關鍵數據(不是財務數據等)
 
  財務數據等是非常重要的數據,絕對不允許出現或使用無效的數據,所以此時為了安全起見最好不要使用二級緩存。
  因為此時 「正確性」的重要性遠大於 「高績效」的重要性。
 
2.     在系統中使用hibernate快取的建議
1.4.   目前狀況
 一般系統中有三種情況會繞過hibernate執行資料庫操作:

1、多個應用系統同時存取一個資料庫使用資料來源二級快取會不可避免的造成資料不一致的問題,
   此時要進行詳細的設計。例如在設計上避免對相同資料表的同時的寫入操作,
   使用資料庫各種層級的鎖定機制等。
 
2、動態表相關

   所謂「動態表」是指在系統運作時會根據使用者的作業系統自動建立的資料表。

   例如「自訂表單」等屬於使用者自訂擴充功能開發性質的功能模組,因為此時資料表是執行時間建立的,所以不能進行hibernate的對應。因此對它的操作只能是繞過hibernate的直接資料庫JDBC操作。

      如果此時動態表中的資料沒有設計緩存,就沒有資料不一致的問題。

   如果此時自行設計了快​​取機制,則呼叫自己的快取同步方法即可。

3、使用sql對hibernate持久化物件表進行批次刪除時

     此時執行批次刪除後,快取中會存在已刪除的資料。

分析: 
   當執行了第3條(sql批次刪除)後,後續的查詢只可能是以下三種方式:
a. session.find()方法:
根據前面的總結,find方法不會查詢二級快取的數據,而是直接查詢資料庫。
所以不存在數據有效性的問題。
b. 呼叫iterate方法執行條件查詢時:
根據iterate查詢方法的執行方式,其每次都會到數據庫中查詢滿足條件的id值,然後再根據此id 到緩存中獲取數據,當緩存中沒有此id的資料才會執行資料庫查詢;
如果此記錄已被sql直接刪除,則iterate在執行id查詢時不會將此id查詢出來。所以,即便快取中有此筆記錄也不會被客戶取得,也就不存在不一致的情況。 (此情況經過測試驗證)
 
c. 用get或load方法按id執行查詢:
 
客觀上此時會查詢得到已過期的資料。但又因為系統中執行sql批量刪除一般是

針對中間關聯資料表,對於

中間關聯表的查詢通常都是採用條件查詢,按id來查詢某一條關聯關係的幾率很低,所以此問題也不存在!
 
   如果某個值對象確實需要按id查詢一條關聯關係,同時又因為資料量大使用了sql執行批次刪除。當滿足此兩個條件時,為了保證按id 的查詢得到正確的結果,可以使用手動清楚二級緩存中此對象的數據的方法!!
(此種情況出現的可能性較小)
 
1.5 .   建議
1、建議不要使用sql直接執行資料持久化物件的資料的更新,但是可以執行批次刪除。 (系統中需要批次更新的地方也較少)
 
2、如果必須使用sql執行資料的更新,必須清空此物件的快取資料。呼叫
SessionFactory.evict(class) 
SessionFactory.evict(class,id)
等方法。
 
3、在批次刪除資料量不大的時候可以直接採用hibernate的批次刪除,這樣就不存在繞開hibernate執行sql產生的快取資料一致性的問題。
 
4、不建議採用hibernate的批次刪除方法來刪除大量的記錄資料。
原因是hibernate的批次刪除會執行1個查詢語句外加 滿足條件的n條刪除語句。而不是一次執行一條條件刪除語句! ! 
當待刪除的資料很多時會有很大的效能瓶頸! ! !如果大量刪除資料量較大,例如超過50條,可以採用JDBC直接刪除。這樣作的好處是只執行一條sql刪除語句,效能會有很大的改善。同時,快取資料同步的問題,可以採用 hibernate清除二級快取中的相關資料的方法。
呼叫 SessionFactory.evict(class) ;SessionFactory.evict(class,id)等方法。
 
所以說,對於一般的應用系統開發而言(不涉及到集群,分佈式資料同步問題等),因為只在中間關聯表執行批量刪除時調用了sql執行,同時中間關聯表一般是執行條件查詢不太可能執行按id查詢。所以,此時可以直接執行sql刪除,甚至不需要呼叫快取的清除方法。這樣做不會導致日後配置了二級快取造成資料有效性的問題。
 
退一步說,即使以後真的呼叫了按id查詢中間表物件的方法,也可以透過呼叫清除快取的方法來解決。

 

4、具體的配置方法 
根據我了解的很多hibernate的用戶在調用其相應方法時都迷信的相信“hibernate會自行為我們處理性能的問題”,或者“hibernate會自動為我們的所有操作調用緩存”,實際的情況是hibernate雖然為我們提供了很好的緩存機制和擴展緩存框架的支持,但是必須經過正確的調用其才有可能發揮作用! !所以造成很多使用hibernate的系統的效能問題,其實並不是hibernate不行或不好,而是因為使用者沒有正確的了解其使用方法造成的。相反,如果配置得當hibernate的性能表現會讓你有相當“驚喜的”發現。下面我說明特定的設定方法.

 ibernate提供了二級快取的介面: 
net.sf.hibernate.cache.Provider, 
同時提供了一個預設的實作net.sf.hibernate.cache.HashtableCacheProvider, 可以配置其他的實作例如ehcache,jbosscache等。

具體的設定位置位於hibernate.cfg.xml檔案中 

true 
natesf. .cache.HashtableCacheProvider

很多的hibernate使用者在設定到這一步驟就以為完事了, 

注意:其實光這樣配,根本就沒有使用hibernate的二級快取。同時因為他們在使用hibernate時大多時候是馬上關閉session,所以,一級快取也沒有起到任何作用。結果就是沒有使用任何緩存,所有的hibernate操作都是直接操作的資料庫! !性能可以想見。

正確的方法是除了以上的配置外還應該配置每個vo物件的特定快取策略,在影射檔案中配置。例如:

 

 
 
 name="id" column="TYPEID" type="java.lang.Long"> 
 

 
 
 


關鍵就是這個,其有幾個選擇 
read-only,read-write,transactional,等 
然後在執行查詢時注意了,如果是條件查詢,或傳回所有結果的查詢,此時session.find()方法不會取得快取中的資料。只有在呼叫query.iterate()方法時才會調快取的資料。

同時get 和load方法是都會查詢快取中的資料.

對於不同的快取框架具體的配置方法會有不同,但是大體是以上的配置

(另外,對於支援事務型,以及支援叢集的環境的配置我會爭取在後續的文章中發表出來)

 

3.     總結
總之是根據不同的業務狀況和專案狀況對hibernate進行有效的配置和正確的使用,揚長避短。不存在適合於任何情況的一個「萬能」的方案。


陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
.NET中的C#代碼:探索編程過程.NET中的C#代碼:探索編程過程Apr 12, 2025 am 12:02 AM

C#在.NET中的編程過程包括以下步驟:1)編寫C#代碼,2)編譯為中間語言(IL),3)由.NET運行時(CLR)執行。 C#在.NET中的優勢在於其現代化語法、強大的類型系統和與.NET框架的緊密集成,適用於從桌面應用到Web服務的各種開發場景。

C#.NET:探索核心概念和編程基礎知識C#.NET:探索核心概念和編程基礎知識Apr 10, 2025 am 09:32 AM

C#是一種現代、面向對象的編程語言,由微軟開發並作為.NET框架的一部分。 1.C#支持面向對象編程(OOP),包括封裝、繼承和多態。 2.C#中的異步編程通過async和await關鍵字實現,提高應用的響應性。 3.使用LINQ可以簡潔地處理數據集合。 4.常見錯誤包括空引用異常和索引超出範圍異常,調試技巧包括使用調試器和異常處理。 5.性能優化包括使用StringBuilder和避免不必要的裝箱和拆箱。

測試C#.NET應用程序:單元,集成和端到端測試測試C#.NET應用程序:單元,集成和端到端測試Apr 09, 2025 am 12:04 AM

C#.NET應用的測試策略包括單元測試、集成測試和端到端測試。 1.單元測試確保代碼的最小單元獨立工作,使用MSTest、NUnit或xUnit框架。 2.集成測試驗證多個單元組合的功能,常用模擬數據和外部服務。 3.端到端測試模擬用戶完整操作流程,通常使用Selenium進行自動化測試。

高級C#.NET教程:ACE您的下一次高級開發人員面試高級C#.NET教程:ACE您的下一次高級開發人員面試Apr 08, 2025 am 12:06 AM

C#高級開發者面試需要掌握異步編程、LINQ、.NET框架內部工作原理等核心知識。 1.異步編程通過async和await簡化操作,提升應用響應性。 2.LINQ以SQL風格操作數據,需注意性能。 3..NET框架的CLR管理內存,垃圾回收需謹慎使用。

C#.NET面試問題和答案:提高您的專業知識C#.NET面試問題和答案:提高您的專業知識Apr 07, 2025 am 12:01 AM

C#.NET面試問題和答案包括基礎知識、核心概念和高級用法。 1)基礎知識:C#是微軟開發的面向對象語言,主要用於.NET框架。 2)核心概念:委託和事件允許動態綁定方法,LINQ提供強大查詢功能。 3)高級用法:異步編程提高響應性,表達式樹用於動態代碼構建。

使用C#.NET建築微服務:建築師實用指南使用C#.NET建築微服務:建築師實用指南Apr 06, 2025 am 12:08 AM

C#.NET是構建微服務的熱門選擇,因為其生態系統強大且支持豐富。 1)使用ASP.NETCore創建RESTfulAPI,處理訂單創建和查詢。 2)利用gRPC實現微服務間的高效通信,定義和實現訂單服務。 3)通過Docker容器化微服務,簡化部署和管理。

C#.NET安全性最佳實踐:防止常見漏洞C#.NET安全性最佳實踐:防止常見漏洞Apr 05, 2025 am 12:01 AM

C#和.NET的安全最佳實踐包括輸入驗證、輸出編碼、異常處理、以及身份驗證和授權。 1)使用正則表達式或內置方法驗證輸入,防止惡意數據進入系統。 2)輸出編碼防止XSS攻擊,使用HttpUtility.HtmlEncode方法。 3)異常處理避免信息洩露,記錄錯誤但不返回詳細信息給用戶。 4)使用ASP.NETIdentity和Claims-based授權保護應用免受未授權訪問。

c語言中:是什麼意思c語言中:是什麼意思Apr 03, 2025 pm 07:24 PM

C 語言中冒號 (':') 的含義:條件語句:分隔條件表達式和語句塊循環語句:分隔初始化、條件和增量表達式宏定義:分隔宏名和宏值單行註釋:表示從冒號到行尾的內容為註釋數組維數:指定數組的維數

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
4 週前By尊渡假赌尊渡假赌尊渡假赌

熱工具

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Atom編輯器mac版下載

Atom編輯器mac版下載

最受歡迎的的開源編輯器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器