




已閱讀5頁,還剩14頁未讀, 繼續(xù)免費閱讀
版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
第11章Hibernate的高級特性,11.1Hibernate的事務管理,11.2Hibernate的并發(fā),11.3Hibernate的攔截器,11.1Hibernate的事務管理,11.1.1事務的概念事務有4個重要特性:原子性:即作為一個事務,它是一個不可分割的整體,只有全部操作都完成了,才算結束;其中任何一個操作執(zhí)行失敗,整個事務都要撤銷。一致性:即事務不能破壞數(shù)據(jù)庫的完整性和業(yè)務邏輯的一致性。事務不管成功還是失敗,事務結束時,整個數(shù)據(jù)庫內(nèi)部數(shù)據(jù)都是正確的。隔離性:即在并發(fā)的數(shù)據(jù)庫操作時,不同的事務操作相同的數(shù)據(jù)時,每個事務都有自己的完整的數(shù)據(jù)空間。一個事務不會看到或拿到另一個事務正修改到一半的數(shù)據(jù),這些數(shù)據(jù)要么是另一個事務修改前的,要么是另一個事務修改后提交的。擁有這個特性,是為了在數(shù)據(jù)庫并發(fā)操作過程中,保證所有并發(fā)操作的正確性。持久性:即事務成功提交后,數(shù)據(jù)就被永久地保存到數(shù)據(jù)庫,重新啟動數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)仍然保存在數(shù)據(jù)庫系統(tǒng)中。,11.1.2Hibernate的事務,將事務管理委托給JDBC進行處理是最簡單的實現(xiàn)方式,Hibernate對于JDBC事務的封裝也比較簡單。例如下面的代碼:Sessionsession=sessionFactory.openSession();Transactiontx=session.beginTransaction();mit();從JDBC層面而言,上面的代碼實際上對應著:Connectioncn=getConnection;cn.setAutoCommit(false);/JDBC調用相關的SQL語句mit();,11.1.2Hibernate的事務,在sessionFactory.openSession()語句中,Hibernate會初始化數(shù)據(jù)庫連接。與此同時,將其AutoCommit設為關閉狀態(tài)(false),即一開始從SessionFactory獲得的session,其自動提交屬性已經(jīng)被關閉。下面的代碼不會對數(shù)據(jù)庫產(chǎn)生任何效果:sessionsession=session.Factory.openSession();session.save(user);session.close();這實際上相當于JDBCConnection的AutoCommit屬性被設為false,執(zhí)行了若干JDBC操作之后,沒有調用commit操作。如果要使代碼真正作用到數(shù)據(jù)庫,必須顯示地調用Transaction指令,例如下面的代碼:Sessionsession=sessionFactory.openSession();Transactiontx=sessio.beginTransaction();session.save(user);mit();session.close();,11.1.2Hibernate的事務,Hibernate的事務應用一般分為下面幾個步驟:(1)通過SessionFactoy獲得Session對象,例如下面的代碼:Sessionsession=sessionFactory.openSession();(2)通過Session對象開始一個事務,例如下面的代碼:Transactiont=session.beginTransaction();(3)進行相關的數(shù)據(jù)操作。(4)事務提交,例如下面的代碼:mit();(5)如果事務處理出現(xiàn)異常,則撤銷事務(通常叫做事務回滾),例如下面的代碼:t.rollback();(6)關閉Session,結束操作,例如下面的代碼:session.close();一個完整的應用Hibernate事務的實例。,11.1.2Hibernate的事務,2基于JTA的事務管理概念JTA(JavaTransactionAPI)是由JavaEETransactionManager管理的事務,其最大的特點是調用UserTransaction接口的begin()、commit()和rollback()方法來完成事務范圍的界定、事務的提交和回滾。JTA可以實現(xiàn)同一事務對應不同的數(shù)據(jù)庫。JTA主要用于分布式的多個數(shù)據(jù)源的兩階段提交的事務,而JDBC的Connection提供單個數(shù)據(jù)源的事務,后者因為只涉及一個數(shù)據(jù)源,所以其事務可以由數(shù)據(jù)庫自己單獨實現(xiàn),而JTA事務因為其分布式和多數(shù)據(jù)源的特性,不可能由任何一個數(shù)據(jù)源實現(xiàn)事務。因此,JTA中的事務是由“事務管理器”來實現(xiàn)的,它會在多個數(shù)據(jù)源之間統(tǒng)籌事務,具體使用的技術就是所謂的“兩階段提交”。JTA事務管理由JTA容器實現(xiàn),JTA容器對當前加入事務的眾多Connection進行調度,實現(xiàn)事務性要求。JTA的事務周期可橫跨多個JDBCConnection生命周期。同樣,對于基于JTA事務的Hibernate而言,JTA事務橫跨多個Session。,11.2Hibernate的并發(fā),11.2.1并發(fā)產(chǎn)生的問題一般情況下,數(shù)據(jù)庫并發(fā)產(chǎn)生的問題可以分為4種:更新丟失、臟讀、不可重復讀及虛讀。下面分別介紹這4種問題。更新丟失。當多個事務同時操作同一數(shù)據(jù)時,由于事務之間完全沒有進行隔離,撤銷其中一個事務,結果覆蓋了其他事務已經(jīng)提交并成功更新的數(shù)據(jù),對其他事務而言造成了數(shù)據(jù)丟失。例如,在存款和取款的情況下,如果沒有采取措施,很容易出現(xiàn)如表11.1所示的并發(fā)問題帶來的情況。,表11.1更新丟失,11.2.1并發(fā)產(chǎn)生的問題,臟讀。當多個事務同時操作同一數(shù)據(jù)時,如果事務A讀到事務B尚未提交的更新數(shù)據(jù),且對其進行操作,當事務B撤銷了更新后,事務A所操作的數(shù)據(jù)便成了無效數(shù)據(jù)(即臟數(shù)據(jù))。同樣以存款與取款問題為例,如表11.2所示。,表11.2臟讀,11.2.1并發(fā)產(chǎn)生的問題,虛讀。當多個事務同時操作同一數(shù)據(jù)時,如果事務A在操作過程中進行兩次查詢,很有可能第二次查詢的結果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)(這里并不要求兩次查詢的SQL語句相同)。這是因為,在兩次查詢過程中由事務B插入了新數(shù)據(jù)造成的,如表11.3所示。,表11.3虛讀,11.2.1并發(fā)產(chǎn)生的問題,不可重復讀。當多個事務同時操作同一數(shù)據(jù)時,如果事務A對同一行數(shù)據(jù)重復讀取兩次,卻得到了不同的結果,有可能在事務A兩次讀取的過程中,由事務B對該行數(shù)據(jù)進行了修改,并成功提交,如表11.4所示。,表11.4不可重復讀,11.2.2解決方案,1設置隔離級別標準SQL規(guī)范中提供了4種事務隔離級別,可以通過Hibernate的配置文件來設置隔離級別。串行化(Serializable):提供嚴格的事務隔離。它要求各事務串行化執(zhí)行,事務只能一個接著一個地串行執(zhí)行,不能并發(fā)執(zhí)行。當數(shù)據(jù)庫采用此隔離級別時,只要有一個事務在操作某個數(shù)據(jù),其他欲操作此數(shù)據(jù)的事務必須停下來等待,直至那個事務結束,有效地防止了所有可能出現(xiàn)的并發(fā)問題,但并發(fā)性能較低??芍貜妥x?。≧epeatableRead):當數(shù)據(jù)庫采用此隔離級別時,一個事務在執(zhí)行過程中可以訪問其他事務成功提交的新插入的數(shù)據(jù),但不能訪問成功修改的數(shù)據(jù),因而有效地防止了不可重復讀取和臟讀兩類并發(fā)問題的發(fā)生。讀已提交數(shù)據(jù)(ReadCommitted):當數(shù)據(jù)庫采用此隔離級別時,一個事務在執(zhí)行過程中既可以訪問其他事務成功提交的新插入的數(shù)據(jù),又可以訪問成功修改的數(shù)據(jù),因而有效地防止了臟讀。讀未提交數(shù)據(jù)(ReadUncommitted):當數(shù)據(jù)庫采用此隔離級別時,一個事務在執(zhí)行過程中既可以訪問其他事務未提交的新插入的數(shù)據(jù),又可以訪問未提交的修改數(shù)據(jù),因而僅僅防止了更新丟失的發(fā)生。,11.2.2解決方案,2鎖Hibernate支持兩種鎖機制,悲觀鎖(PessimisticLocking)和樂觀鎖(OptimisticLocking)。悲觀鎖是指對數(shù)據(jù)被外界修改持保守態(tài)度。假定任何時刻存取數(shù)據(jù)時,都可能有一個客戶也正在存取同一數(shù)據(jù),為了保持數(shù)據(jù)被操作的移植性,于是對數(shù)據(jù)采取了數(shù)據(jù)庫層次的鎖定狀態(tài),依靠數(shù)據(jù)庫提供的鎖機制來實現(xiàn)。樂觀鎖則樂觀地認為數(shù)據(jù)很少發(fā)生同時存取的問題,因而不做數(shù)據(jù)庫層次上的鎖定。為了維護正確的數(shù)據(jù),樂觀鎖采用應用程序上的邏輯實現(xiàn)版本控制的方法。Hibernate中以通過版本號檢索來實現(xiàn)更新為主,這也是Hibernate推薦的方式。在數(shù)據(jù)庫中假如有一個Version記錄,在讀取數(shù)據(jù)時連帶版本號一同讀取,并在更新數(shù)據(jù)時遞增版本號,然后比較此版本號和數(shù)據(jù)庫中的版本號,如果大于數(shù)據(jù)庫中的版本號,則給予更新,否則就報錯誤。,11.3Hibernate的攔截器,11.3.1Interceptor接口下面分別介紹這些方法的含義及執(zhí)行階段。afterTransactionBegin(Transactiontx):當Hibernate事務被調用后,該方法將被調用。afterTransactionCompletion(Transactiontx):當事務被提交或回滾后,該方法被調用。beforeTransactionCompletion(Transactiontx):該方法在一個事務提交前被調用,但是回滾前不被調用。findDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyNames,Typetypes):當調用flush()方法刷新緩存時會自動調用這個方法檢查緩存中是否有臟數(shù)據(jù)(緩存中有數(shù)據(jù)庫不一致的數(shù)據(jù))。返回的數(shù)組是對象臟屬性的索引。如果該數(shù)組不為空,說明這個對象需要被更新;如果是空的數(shù)組,說明這個對象不必被更新,默認返回null。Hibernate會自動使用默認的方式檢查對象是否是臟數(shù)據(jù)。onDelete(ObjectSerializableid,Objectstate,StringpropertyName,Typetypes):在對象刪除前被調用。不建議使用給“state”參數(shù)賦值來修改要被刪除實體的屬性值。,11.3.1Interceptor接口,onFlushDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyNames,Typetypes):如果一個對象在flush執(zhí)行時被發(fā)現(xiàn)是臟數(shù)據(jù),則這個方法會被調用。可以給“currentState”參數(shù)賦值,這個賦值既會修改持久化類對象的屬性值,也會修改數(shù)據(jù)庫表對應的列值。不建議使用給“previousState”賦值來修改實體更新前的屬性值。返回值是boolean類型,true說明在方法體中修改了對象的屬性值“currentState”,false說明沒有修改其當前屬性值。onLoad(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typtypes):當一個對象從數(shù)據(jù)庫中載入時被調用。修改“state”參數(shù),就可以修改持久化類對象的屬性值。返回值是boolean類型,true說明在方法體中修改了對象的屬性值state,false表示沒有修改。onSave(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typetypes):在一個方法保存之前被調用。如果給相應的“state”賦值,這個值能夠被insert語句保存到數(shù)據(jù)庫中,同時也更改持久化類對象的屬性值。返回boolean類型,true代表用戶在其中修改了屬性值state,false表示沒有修改。,11.3.1Interceptor接口,onCollectionRecreate(Objectcollection,Serializablekey):在集合被創(chuàng)建或再次創(chuàng)建時被調用。如果一個持久化類中使用了Java集合屬性,那么保存這個持久化類時,這個集合屬性中的元素也被同時保存,這個onCollectionRecreate()方法會被自動調用。onCollectionRemove(Objectcollection,Serializablekey):在集合被刪除時被調用。onCollectionUpdate(Objectcollection,Serializablekey):在集合被更新時被調用。isTransient(Objectentity):調用這個方法可以判斷一個實體是持久化態(tài)還是游離態(tài)。返回值是boolean類型,如果返回true,代表這個實體是持久化態(tài);如果返回false,代表這個實體是游離態(tài);如果返回null,說明Hibernate使用映射文件中的unsaved-value或者其他方法來判斷,這個實體還沒有被保存,是臨時態(tài)。getEntity(StringentityName,Serializableid):以對象名字和id為參數(shù),可以返回持久化對象實體。getEntityName(Objectobject):以持久態(tài)和游離態(tài)的實體類對象為參數(shù),可以返回實體的名字。,11.3.1Interceptor接口,instantiate(StringentityName,EntityModeentityMode,Serializableid):這個方法可以顯式地讓Hibernate實例化一個實體類。參數(shù)entityName是實體對象的名字,entityMode是返回的實體實例的類型,參數(shù)id將作為新實體對象的id。onPrepareStatement(Str
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 主軸安裝施工方案
- 天棚找補施工方案
- 2025至2030年中國便攜貴金屬檢測儀數(shù)據(jù)監(jiān)測研究報告
- 2025年中國透明音箱線市場調查研究報告
- 人行跑道施工方案
- 人教版初中化學九年級上冊 第三單元課題3 元素 教學設計(1)001
- 8我們受特殊保護 課時3《特殊關愛 助我成長》教學設計-2024-2025學年道德與法治六年級上冊統(tǒng)編版
- 《孤獨的小螃蟹》導讀課(教學設計)-2024-2025學年統(tǒng)編版語文二年級上冊
- 球罐拆除施工方案
- 佳木斯2024年黑龍江佳木斯大學招聘27人筆試歷年參考題庫附帶答案詳解
- 2025山東省港口集團有限公司招聘183人筆試參考題庫附帶答案詳解
- 2025青桐鳴高三4月大聯(lián)考數(shù)學試題及答案
- 初級會計師考試歷年真題試題及答案
- 水利部珠江水利委員會所屬事業(yè)單位招聘筆試真題2024
- 真需求-打開商業(yè)世界的萬能鑰匙
- 2025屆湖北省武漢市高考數(shù)學一模試卷含解析
- 河北省縣市鄉(xiāng)鎮(zhèn)衛(wèi)生院社區(qū)衛(wèi)生服務中心基本公共衛(wèi)生服務醫(yī)療機構名單目錄地址2415家
- 《膀胱結石的護理》PPT課件.ppt
- 制造型企業(yè)的營銷策略分析
- 旋風式除塵器使用說明書
- 儀表著陸系統(tǒng)
評論
0/150
提交評論