Hibernate并沒有為巨型數據集合提供良好的幫助,這也許是開發者認為這樣沒有太大必要,反而增加Hibernate框架復雜性的緣故吧。最近在Hibernate的官方壇子上看到Gavin寫給初級用戶的“understand FlushMode.NEVER”,并參考了一下Stripes項目(本人時常關注的時髦項目)作者Tim的blog。在閱讀兩位大家言論后,和大家share一下。
一、案件背景:

Hibernate并沒有為巨型數據集合提供良好的幫助,這也許是開發者認為這樣沒有太大必要,反而增加Hibernate框架復雜性的緣故吧。于是“極大數據量==批量處理”、“Hibernate/java不是批處理的最佳場所”的觀念在Hibernate開發中大行其道,有些開發者甚至直接利用Hibernate建立session,獲取其connection進而進行jdbc操作。Jdbc并不是古董,但在Hibernate中再次call它,難免有些令人無奈。最近在Hibernate的官方壇子上看到Gavin寫給初級用戶的“understand FlushMode.NEVER”,并參考了一下Stripes項目(本人時常關注的時髦項目)作者Tim的blog。在閱讀兩位大家言論后,和大家share一下。
二、性能殺手何在?

Tim在其Blog寫道:“我目前的DNA重組系統,具有復雜而海量的OLTP數據,對付這些在內存的復雜對象(數千個)的方式是依靠用戶接口(非批量處理)來實現用例驅動。”這句半開玩笑的話,是我想起了那男耕女織的生產力低下的生活,真的讓每個開發者都使用算盤運算嗎?
session.setFlushMode(FlushMode.NEVER);
這條語句及其簡單,但解決了大問題。它告知Hibernate session無論何時也不要flush任何的狀態變化到數據庫,除非開發者直接調用session.flush()。聽上去很合乎邏輯,但它為何在一些場景中對性能影響甚深,而在其他的場景中卻好似輕如鵝毛般?
在Tim的項目中存在著一個十分典型的case(我也不大了解生物,這不能怪我):在實驗中利用PCR PRimers對遺傳基因(genes)和DNA中的核苷酸序列(exons),這里的PCR Primers是在PCR處理過程中用于檢測DNA片段的物質,對不起大家,本人對生物學詞匯實在無能為力。檢測匹配過程大致分為以下7步:
1.發現本次實驗中所有exons(個數在5000個以上);
2.查詢本次實驗所有已經排序的PCR Primers;
3.查詢本次實驗所有待排序的PCR Primers;
4.得到與exons對應的Primers找出那些無需轉換的部分;
5.在系統中為無需轉換的區域查詢所有可能的PCR Primers;
6.測試每個primer找出最佳exons匹配者(Primer);
7.保存找出的Primer。
不用擔心,步驟細節不大明白也不會影響后面的理解。
由于domain model極其海量,在第4步我們可能在一個session中排序20000-30000個對象。而在5、6步的查詢將帶來0-20個附加對象。有趣之處在于當執行第7步將對象save到數據庫時,沒有一個前面裝載的對象被修改過。整個實驗的目的就是僅僅獲得這0-20個對象。
在回顧了Tim的生物學場景之后,讓我們重新回到FlushMode.NEVER的討論上來吧。你可能認為既然直到最后一步都沒有修改或是持久化任何東西,那么改變flush模式將收效甚微。當然這是不正確的未參透實質的理解。實際上,在上面流程的起始設置Never這個flush模式、在流程終點手動flush將節省一半的run time,請注重這里僅提到了run time而沒有將內存、IO計算在內。
三、這個殺手不太“冷”

新聞熱點
疑難解答