Hibernate的高級(jí)特性.ppt_第1頁
Hibernate的高級(jí)特性.ppt_第2頁
Hibernate的高級(jí)特性.ppt_第3頁
Hibernate的高級(jí)特性.ppt_第4頁
Hibernate的高級(jí)特性.ppt_第5頁
已閱讀5頁,還剩14頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第11章Hibernate的高級(jí)特性,11.1Hibernate的事務(wù)管理,11.2Hibernate的并發(fā),11.3Hibernate的攔截器,11.1Hibernate的事務(wù)管理,11.1.1事務(wù)的概念事務(wù)有4個(gè)重要特性:原子性:即作為一個(gè)事務(wù),它是一個(gè)不可分割的整體,只有全部操作都完成了,才算結(jié)束;其中任何一個(gè)操作執(zhí)行失敗,整個(gè)事務(wù)都要撤銷。一致性:即事務(wù)不能破壞數(shù)據(jù)庫的完整性和業(yè)務(wù)邏輯的一致性。事務(wù)不管成功還是失敗,事務(wù)結(jié)束時(shí),整個(gè)數(shù)據(jù)庫內(nèi)部數(shù)據(jù)都是正確的。隔離性:即在并發(fā)的數(shù)據(jù)庫操作時(shí),不同的事務(wù)操作相同的數(shù)據(jù)時(shí),每個(gè)事務(wù)都有自己的完整的數(shù)據(jù)空間。一個(gè)事務(wù)不會(huì)看到或拿到另一個(gè)事務(wù)正修改到一半的數(shù)據(jù),這些數(shù)據(jù)要么是另一個(gè)事務(wù)修改前的,要么是另一個(gè)事務(wù)修改后提交的。擁有這個(gè)特性,是為了在數(shù)據(jù)庫并發(fā)操作過程中,保證所有并發(fā)操作的正確性。持久性:即事務(wù)成功提交后,數(shù)據(jù)就被永久地保存到數(shù)據(jù)庫,重新啟動(dòng)數(shù)據(jù)庫系統(tǒng)后,數(shù)據(jù)仍然保存在數(shù)據(jù)庫系統(tǒng)中。,11.1.2Hibernate的事務(wù),將事務(wù)管理委托給JDBC進(jìn)行處理是最簡單的實(shí)現(xiàn)方式,Hibernate對(duì)于JDBC事務(wù)的封裝也比較簡單。例如下面的代碼:Sessionsession=sessionFactory.openSession();Transactiontx=session.beginTransaction();mit();從JDBC層面而言,上面的代碼實(shí)際上對(duì)應(yīng)著:Connectioncn=getConnection;cn.setAutoCommit(false);/JDBC調(diào)用相關(guān)的SQL語句mit();,11.1.2Hibernate的事務(wù),在sessionFactory.openSession()語句中,Hibernate會(huì)初始化數(shù)據(jù)庫連接。與此同時(shí),將其AutoCommit設(shè)為關(guān)閉狀態(tài)(false),即一開始從SessionFactory獲得的session,其自動(dòng)提交屬性已經(jīng)被關(guān)閉。下面的代碼不會(huì)對(duì)數(shù)據(jù)庫產(chǎn)生任何效果:sessionsession=session.Factory.openSession();session.save(user);session.close();這實(shí)際上相當(dāng)于JDBCConnection的AutoCommit屬性被設(shè)為false,執(zhí)行了若干JDBC操作之后,沒有調(diào)用commit操作。如果要使代碼真正作用到數(shù)據(jù)庫,必須顯示地調(diào)用Transaction指令,例如下面的代碼:Sessionsession=sessionFactory.openSession();Transactiontx=sessio.beginTransaction();session.save(user);mit();session.close();,11.1.2Hibernate的事務(wù),Hibernate的事務(wù)應(yīng)用一般分為下面幾個(gè)步驟:(1)通過SessionFactoy獲得Session對(duì)象,例如下面的代碼:Sessionsession=sessionFactory.openSession();(2)通過Session對(duì)象開始一個(gè)事務(wù),例如下面的代碼:Transactiont=session.beginTransaction();(3)進(jìn)行相關(guān)的數(shù)據(jù)操作。(4)事務(wù)提交,例如下面的代碼:mit();(5)如果事務(wù)處理出現(xiàn)異常,則撤銷事務(wù)(通常叫做事務(wù)回滾),例如下面的代碼:t.rollback();(6)關(guān)閉Session,結(jié)束操作,例如下面的代碼:session.close();一個(gè)完整的應(yīng)用Hibernate事務(wù)的實(shí)例。,11.1.2Hibernate的事務(wù),2基于JTA的事務(wù)管理概念JTA(JavaTransactionAPI)是由JavaEETransactionManager管理的事務(wù),其最大的特點(diǎn)是調(diào)用UserTransaction接口的begin()、commit()和rollback()方法來完成事務(wù)范圍的界定、事務(wù)的提交和回滾。JTA可以實(shí)現(xiàn)同一事務(wù)對(duì)應(yīng)不同的數(shù)據(jù)庫。JTA主要用于分布式的多個(gè)數(shù)據(jù)源的兩階段提交的事務(wù),而JDBC的Connection提供單個(gè)數(shù)據(jù)源的事務(wù),后者因?yàn)橹簧婕耙粋€(gè)數(shù)據(jù)源,所以其事務(wù)可以由數(shù)據(jù)庫自己單獨(dú)實(shí)現(xiàn),而JTA事務(wù)因?yàn)槠浞植际胶投鄶?shù)據(jù)源的特性,不可能由任何一個(gè)數(shù)據(jù)源實(shí)現(xiàn)事務(wù)。因此,JTA中的事務(wù)是由“事務(wù)管理器”來實(shí)現(xiàn)的,它會(huì)在多個(gè)數(shù)據(jù)源之間統(tǒng)籌事務(wù),具體使用的技術(shù)就是所謂的“兩階段提交”。JTA事務(wù)管理由JTA容器實(shí)現(xiàn),JTA容器對(duì)當(dāng)前加入事務(wù)的眾多Connection進(jìn)行調(diào)度,實(shí)現(xiàn)事務(wù)性要求。JTA的事務(wù)周期可橫跨多個(gè)JDBCConnection生命周期。同樣,對(duì)于基于JTA事務(wù)的Hibernate而言,JTA事務(wù)橫跨多個(gè)Session。,11.2Hibernate的并發(fā),11.2.1并發(fā)產(chǎn)生的問題一般情況下,數(shù)據(jù)庫并發(fā)產(chǎn)生的問題可以分為4種:更新丟失、臟讀、不可重復(fù)讀及虛讀。下面分別介紹這4種問題。更新丟失。當(dāng)多個(gè)事務(wù)同時(shí)操作同一數(shù)據(jù)時(shí),由于事務(wù)之間完全沒有進(jìn)行隔離,撤銷其中一個(gè)事務(wù),結(jié)果覆蓋了其他事務(wù)已經(jīng)提交并成功更新的數(shù)據(jù),對(duì)其他事務(wù)而言造成了數(shù)據(jù)丟失。例如,在存款和取款的情況下,如果沒有采取措施,很容易出現(xiàn)如表11.1所示的并發(fā)問題帶來的情況。,表11.1更新丟失,11.2.1并發(fā)產(chǎn)生的問題,臟讀。當(dāng)多個(gè)事務(wù)同時(shí)操作同一數(shù)據(jù)時(shí),如果事務(wù)A讀到事務(wù)B尚未提交的更新數(shù)據(jù),且對(duì)其進(jìn)行操作,當(dāng)事務(wù)B撤銷了更新后,事務(wù)A所操作的數(shù)據(jù)便成了無效數(shù)據(jù)(即臟數(shù)據(jù))。同樣以存款與取款問題為例,如表11.2所示。,表11.2臟讀,11.2.1并發(fā)產(chǎn)生的問題,虛讀。當(dāng)多個(gè)事務(wù)同時(shí)操作同一數(shù)據(jù)時(shí),如果事務(wù)A在操作過程中進(jìn)行兩次查詢,很有可能第二次查詢的結(jié)果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)(這里并不要求兩次查詢的SQL語句相同)。這是因?yàn)?,在兩次查詢過程中由事務(wù)B插入了新數(shù)據(jù)造成的,如表11.3所示。,表11.3虛讀,11.2.1并發(fā)產(chǎn)生的問題,不可重復(fù)讀。當(dāng)多個(gè)事務(wù)同時(shí)操作同一數(shù)據(jù)時(shí),如果事務(wù)A對(duì)同一行數(shù)據(jù)重復(fù)讀取兩次,卻得到了不同的結(jié)果,有可能在事務(wù)A兩次讀取的過程中,由事務(wù)B對(duì)該行數(shù)據(jù)進(jìn)行了修改,并成功提交,如表11.4所示。,表11.4不可重復(fù)讀,11.2.2解決方案,1設(shè)置隔離級(jí)別標(biāo)準(zhǔn)SQL規(guī)范中提供了4種事務(wù)隔離級(jí)別,可以通過Hibernate的配置文件來設(shè)置隔離級(jí)別。串行化(Serializable):提供嚴(yán)格的事務(wù)隔離。它要求各事務(wù)串行化執(zhí)行,事務(wù)只能一個(gè)接著一個(gè)地串行執(zhí)行,不能并發(fā)執(zhí)行。當(dāng)數(shù)據(jù)庫采用此隔離級(jí)別時(shí),只要有一個(gè)事務(wù)在操作某個(gè)數(shù)據(jù),其他欲操作此數(shù)據(jù)的事務(wù)必須停下來等待,直至那個(gè)事務(wù)結(jié)束,有效地防止了所有可能出現(xiàn)的并發(fā)問題,但并發(fā)性能較低??芍貜?fù)讀?。≧epeatableRead):當(dāng)數(shù)據(jù)庫采用此隔離級(jí)別時(shí),一個(gè)事務(wù)在執(zhí)行過程中可以訪問其他事務(wù)成功提交的新插入的數(shù)據(jù),但不能訪問成功修改的數(shù)據(jù),因而有效地防止了不可重復(fù)讀取和臟讀兩類并發(fā)問題的發(fā)生。讀已提交數(shù)據(jù)(ReadCommitted):當(dāng)數(shù)據(jù)庫采用此隔離級(jí)別時(shí),一個(gè)事務(wù)在執(zhí)行過程中既可以訪問其他事務(wù)成功提交的新插入的數(shù)據(jù),又可以訪問成功修改的數(shù)據(jù),因而有效地防止了臟讀。讀未提交數(shù)據(jù)(ReadUncommitted):當(dāng)數(shù)據(jù)庫采用此隔離級(jí)別時(shí),一個(gè)事務(wù)在執(zhí)行過程中既可以訪問其他事務(wù)未提交的新插入的數(shù)據(jù),又可以訪問未提交的修改數(shù)據(jù),因而僅僅防止了更新丟失的發(fā)生。,11.2.2解決方案,2鎖Hibernate支持兩種鎖機(jī)制,悲觀鎖(PessimisticLocking)和樂觀鎖(OptimisticLocking)。悲觀鎖是指對(duì)數(shù)據(jù)被外界修改持保守態(tài)度。假定任何時(shí)刻存取數(shù)據(jù)時(shí),都可能有一個(gè)客戶也正在存取同一數(shù)據(jù),為了保持?jǐn)?shù)據(jù)被操作的移植性,于是對(duì)數(shù)據(jù)采取了數(shù)據(jù)庫層次的鎖定狀態(tài),依靠數(shù)據(jù)庫提供的鎖機(jī)制來實(shí)現(xiàn)。樂觀鎖則樂觀地認(rèn)為數(shù)據(jù)很少發(fā)生同時(shí)存取的問題,因而不做數(shù)據(jù)庫層次上的鎖定。為了維護(hù)正確的數(shù)據(jù),樂觀鎖采用應(yīng)用程序上的邏輯實(shí)現(xiàn)版本控制的方法。Hibernate中以通過版本號(hào)檢索來實(shí)現(xiàn)更新為主,這也是Hibernate推薦的方式。在數(shù)據(jù)庫中假如有一個(gè)Version記錄,在讀取數(shù)據(jù)時(shí)連帶版本號(hào)一同讀取,并在更新數(shù)據(jù)時(shí)遞增版本號(hào),然后比較此版本號(hào)和數(shù)據(jù)庫中的版本號(hào),如果大于數(shù)據(jù)庫中的版本號(hào),則給予更新,否則就報(bào)錯(cuò)誤。,11.3Hibernate的攔截器,11.3.1Interceptor接口下面分別介紹這些方法的含義及執(zhí)行階段。afterTransactionBegin(Transactiontx):當(dāng)Hibernate事務(wù)被調(diào)用后,該方法將被調(diào)用。afterTransactionCompletion(Transactiontx):當(dāng)事務(wù)被提交或回滾后,該方法被調(diào)用。beforeTransactionCompletion(Transactiontx):該方法在一個(gè)事務(wù)提交前被調(diào)用,但是回滾前不被調(diào)用。findDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyNames,Typetypes):當(dāng)調(diào)用flush()方法刷新緩存時(shí)會(huì)自動(dòng)調(diào)用這個(gè)方法檢查緩存中是否有臟數(shù)據(jù)(緩存中有數(shù)據(jù)庫不一致的數(shù)據(jù))。返回的數(shù)組是對(duì)象臟屬性的索引。如果該數(shù)組不為空,說明這個(gè)對(duì)象需要被更新;如果是空的數(shù)組,說明這個(gè)對(duì)象不必被更新,默認(rèn)返回null。Hibernate會(huì)自動(dòng)使用默認(rèn)的方式檢查對(duì)象是否是臟數(shù)據(jù)。onDelete(ObjectSerializableid,Objectstate,StringpropertyName,Typetypes):在對(duì)象刪除前被調(diào)用。不建議使用給“state”參數(shù)賦值來修改要被刪除實(shí)體的屬性值。,11.3.1Interceptor接口,onFlushDirty(Objectentity,Serializableid,ObjectcurrentState,ObjectpreviousState,StringpropertyNames,Typetypes):如果一個(gè)對(duì)象在flush執(zhí)行時(shí)被發(fā)現(xiàn)是臟數(shù)據(jù),則這個(gè)方法會(huì)被調(diào)用??梢越o“currentState”參數(shù)賦值,這個(gè)賦值既會(huì)修改持久化類對(duì)象的屬性值,也會(huì)修改數(shù)據(jù)庫表對(duì)應(yīng)的列值。不建議使用給“previousState”賦值來修改實(shí)體更新前的屬性值。返回值是boolean類型,true說明在方法體中修改了對(duì)象的屬性值“currentState”,false說明沒有修改其當(dāng)前屬性值。onLoad(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typtypes):當(dāng)一個(gè)對(duì)象從數(shù)據(jù)庫中載入時(shí)被調(diào)用。修改“state”參數(shù),就可以修改持久化類對(duì)象的屬性值。返回值是boolean類型,true說明在方法體中修改了對(duì)象的屬性值state,false表示沒有修改。onSave(Objectentity,Serializableid,Objectstate,StringpropertyNames,Typetypes):在一個(gè)方法保存之前被調(diào)用。如果給相應(yīng)的“state”賦值,這個(gè)值能夠被insert語句保存到數(shù)據(jù)庫中,同時(shí)也更改持久化類對(duì)象的屬性值。返回boolean類型,true代表用戶在其中修改了屬性值state,false表示沒有修改。,11.3.1Interceptor接口,onCollectionRecreate(Objectcollection,Serializablekey):在集合被創(chuàng)建或再次創(chuàng)建時(shí)被調(diào)用。如果一個(gè)持久化類中使用了Java集合屬性,那么保存這個(gè)持久化類時(shí),這個(gè)集合屬性中的元素也被同時(shí)保存,這個(gè)onCollectionRecreate()方法會(huì)被自動(dòng)調(diào)用。onCollectionRemove(Objectcollection,Serializablekey):在集合被刪除時(shí)被調(diào)用。onCollectionUpdate(Objectcollection,Serializablekey):在集合被更新時(shí)被調(diào)用。isTransient(Objectentity):調(diào)用這個(gè)方法可以判斷一個(gè)實(shí)體是持久化態(tài)還是游離態(tài)。返回值是boolean類型,如果返回true,代表這個(gè)實(shí)體是持久化態(tài);如果返回false,代表這個(gè)實(shí)體是游離態(tài);如果返回null,說明Hibernate使用映射文件中的unsaved-value或者其他方法來判斷,這個(gè)實(shí)體還沒有被保存,是臨時(shí)態(tài)。getEntity(StringentityName,Serializableid):以對(duì)象名字和id為參數(shù),可以返回持久化對(duì)象實(shí)體。getEntityName(Objectobject):以持久態(tài)和游離態(tài)的實(shí)體類對(duì)象為參數(shù),可以返回實(shí)體的名字。,11.3.1Interceptor接口,instantiate(StringentityName,EntityModeentityMode,Serializableid):這個(gè)方法可以顯式地讓Hibernate實(shí)例化一個(gè)實(shí)體類。參數(shù)entityName是實(shí)體對(duì)象的名字,entityMode是返回的實(shí)體實(shí)例的類型,參數(shù)id將作為新實(shí)體對(duì)象的id。onPrepareStatement(Str

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論