Denis's Java Library

          The only documentation is the code itself

          導(dǎo)航

          <2005年12月>
          27282930123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567

          統(tǒng)計(jì)

          常用鏈接

          留言簿(2)

          隨筆檔案(8)

          文章分類(2)

          文章檔案(2)

          搜索

          積分與排名

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          2005年12月1日 #

          Spring中的DAO和Service

               摘要: 我們開(kāi)發(fā)程序的目的是為了完成業(yè)務(wù)功能, 理想的情況下程序中的每一條語(yǔ)句都應(yīng)該是與業(yè)務(wù)直接相關(guān)的, 例如程序中不應(yīng)該出現(xiàn)連接數(shù)據(jù)庫(kù), 讀取某個(gè)字段等純技術(shù)性的操作, 而應(yīng)該是得到用戶A的基本信息等具有業(yè)務(wù)含義的操作. dao(data access object)層存在的意。。。。。  閱讀全文

          posted @ 2006-02-05 17:17 DenisLing 閱讀(1626) | 評(píng)論 (0)編輯 收藏

          數(shù)據(jù)庫(kù)設(shè)計(jì)的范式大綱及一個(gè)小的實(shí)例說(shuō)明

           

          數(shù)據(jù)庫(kù)設(shè)計(jì)的范式大綱

          第一范式:

          對(duì)于表中的每一行,必須且僅僅有唯一的行值.在一行中的每一列僅有唯一的值并且具有原子性.

          第二范式:

          第二范式要求非主鍵列是主鍵的子集,非主鍵列活動(dòng)必須完全依賴整個(gè)主鍵。主鍵必須有唯一性的元素,一個(gè)主鍵可以由一個(gè)或更多的組成唯一值的列組成。一旦創(chuàng)建,主鍵無(wú)法改變,外鍵關(guān)聯(lián)一個(gè)表的主鍵。主外鍵關(guān)聯(lián)意味著一對(duì)多的關(guān)系.

          第三范式:

          第三范式要求非主鍵列互不依賴.

          第四范式:

          第四范式禁止主鍵列和非主鍵列一對(duì)多關(guān)系不受約束

          第五范式:

          第五范式將表分割成盡可能小的塊,為了排除在表中所有的冗余.

           

          下面先討論前3個(gè)范式:

           

          引言

            數(shù)據(jù)庫(kù)的設(shè)計(jì)范式是數(shù)據(jù)庫(kù)設(shè)計(jì)所需要滿足的規(guī)范,滿足這些規(guī)范的數(shù)據(jù)庫(kù)是簡(jiǎn)潔的、結(jié)構(gòu)明晰的,同時(shí),不會(huì)發(fā)生插入 (insert)、刪除(delete)和更新(update)操作異常。反之則是亂七八糟,不僅給數(shù)據(jù)庫(kù)的編程人員制造麻煩,而且面目可憎,可能存儲(chǔ)了 大量不需要的冗余信息。

            設(shè)計(jì)范式是不是很難懂呢?非也,大學(xué)教材上給我們一堆數(shù)學(xué)公式我們當(dāng)然看不懂,也記不住。所以我們很多人就根本不按照范式來(lái)設(shè)計(jì)數(shù)據(jù)庫(kù)。

            實(shí)質(zhì)上,設(shè)計(jì)范式用很形象、很簡(jiǎn)潔的話語(yǔ)就能說(shuō)清楚,道明白。本文將對(duì)范式進(jìn)行通俗地說(shuō)明,并以筆者曾經(jīng)設(shè)計(jì)的一個(gè)簡(jiǎn)單論壇的數(shù)據(jù)庫(kù)為例來(lái)講解怎樣將這些范式應(yīng)用于實(shí)際工程。

            范式說(shuō)明

            第一范式(1NF):數(shù)據(jù)庫(kù)表中的字段都是單一屬性的,不可再分。這個(gè)單一屬性由基本類型構(gòu)成,包括整型、實(shí)數(shù)、字符型、邏輯型、日期型等。

            例如,如下的數(shù)據(jù)庫(kù)表是符合第一范式的:

          字段1

          字段2

          字段3

          字段4

           

           

           

           


            而這樣的數(shù)據(jù)庫(kù)表是不符合第一范式的:

          字段1

          字段2

          字段3

          字段4

           

           

          字段3.1

          字段3.2

           







            很顯然,在當(dāng)前的任何關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(DBMS)中,傻瓜也不可能做出不符合第一范式的數(shù)據(jù)庫(kù),因?yàn)檫@些DBMS不允許你把數(shù)據(jù)庫(kù)表的一列再分成二列或多列。因此,你想在現(xiàn)有的DBMS中設(shè)計(jì)出不符合第一范式的數(shù)據(jù)庫(kù)都是不可能的。

            第二范式(2NF):數(shù)據(jù)庫(kù)表中不存在非關(guān)鍵字段對(duì)任一候選關(guān)鍵字段的部分函數(shù)依賴(部分函數(shù)依賴指的是存在組合關(guān)鍵字中的某些字段決定非關(guān)鍵字段的情況),也即所有非關(guān)鍵字段都完全依賴于任意一組候選關(guān)鍵字。

            假定選課關(guān)系表為SelectCourse(學(xué)號(hào), 姓名, 年齡, 課程名稱, 成績(jī), 學(xué)分),關(guān)鍵字為組合關(guān)鍵字(學(xué)號(hào), 課程名稱),因?yàn)榇嬖谌缦聸Q定關(guān)系:

            (學(xué)號(hào), 課程名稱) → (姓名, 年齡, 成績(jī), 學(xué)分)

            這個(gè)數(shù)據(jù)庫(kù)表不滿足第二范式,因?yàn)榇嬖谌缦聸Q定關(guān)系:

            (課程名稱) → (學(xué)分)

            (學(xué)號(hào)) → (姓名, 年齡)

            即存在組合關(guān)鍵字中的字段決定非關(guān)鍵字的情況。

            由于不符合2NF,這個(gè)選課關(guān)系表會(huì)存在如下問(wèn)題:

            (1) 數(shù)據(jù)冗余:

            同一門(mén)課程由n個(gè)學(xué)生選修,"學(xué)分"就重復(fù)n-1次;同一個(gè)學(xué)生選修了m門(mén)課程,姓名和年齡就重復(fù)了m-1次。

            (2) 更新異常:

            若調(diào)整了某門(mén)課程的學(xué)分,數(shù)據(jù)表中所有行的"學(xué)分"值都要更新,否則會(huì)出現(xiàn)同一門(mén)課程學(xué)分不同的情況。

            (3) 插入異常:

            假設(shè)要開(kāi)設(shè)一門(mén)新的課程,暫時(shí)還沒(méi)有人選修。這樣,由于還沒(méi)有"學(xué)號(hào)"關(guān)鍵字,課程名稱和學(xué)分也無(wú)法記錄入數(shù)據(jù)庫(kù)。

            (4) 刪除異常:

            假設(shè)一批學(xué)生已經(jīng)完成課程的選修,這些選修記錄就應(yīng)該從數(shù)據(jù)庫(kù)表中刪除。但是,與此同時(shí),課程名稱和學(xué)分信息也被刪除了。很顯然,這也會(huì)導(dǎo)致插入異常。

            把選課關(guān)系表SelectCourse改為如下三個(gè)表:

            學(xué)生:Student(學(xué)號(hào), 姓名, 年齡);

            課程:Course(課程名稱, 學(xué)分)

            選課關(guān)系:SelectCourse(學(xué)號(hào), 課程名稱, 成績(jī))

            這樣的數(shù)據(jù)庫(kù)表是符合第二范式的,消除了數(shù)據(jù)冗余、更新異常、插入異常和刪除異常。

            另外,所有單關(guān)鍵字的數(shù)據(jù)庫(kù)表都符合第二范式,因?yàn)椴豢赡艽嬖诮M合關(guān)鍵字。

             第三范式(3NF):在第二范式的基礎(chǔ)上,數(shù)據(jù)表中如果不存在非關(guān)鍵字段對(duì)任一候選關(guān)鍵字段的傳遞函數(shù)依賴則符合第三范式。所謂傳遞函數(shù)依賴,指的是如 果存在"A → B → C"的決定關(guān)系,則C傳遞函數(shù)依賴于A。因此,滿足第三范式的數(shù)據(jù)庫(kù)表應(yīng)該不存在如下依賴關(guān)系:

            關(guān)鍵字段非關(guān)鍵字段x → 非關(guān)鍵字段y

            假定學(xué)生關(guān)系表為Student(學(xué)號(hào), 姓名, 年齡, 所在學(xué)院, 學(xué)院地點(diǎn), 學(xué)院電話),關(guān)鍵字為單一關(guān)鍵字"學(xué)號(hào)",因?yàn)榇嬖谌缦聸Q定關(guān)系:

            (學(xué)號(hào)) → (姓名, 年齡, 所在學(xué)院, 學(xué)院地點(diǎn), 學(xué)院電話)

            這個(gè)數(shù)據(jù)庫(kù)是符合2NF的,但是不符合3NF,因?yàn)榇嬖谌缦聸Q定關(guān)系:

            (學(xué)號(hào)) → (所在學(xué)院) → (學(xué)院地點(diǎn), 學(xué)院電話)

            即存在非關(guān)鍵字段"學(xué)院地點(diǎn)"、"學(xué)院電話"對(duì)關(guān)鍵字段"學(xué)號(hào)"的傳遞函數(shù)依賴。

            它也會(huì)存在數(shù)據(jù)冗余、更新異常、插入異常和刪除異常的情況,讀者可自行分析得知。

            把學(xué)生關(guān)系表分為如下兩個(gè)表:

            學(xué)生:(學(xué)號(hào), 姓名, 年齡, 所在學(xué)院)

            學(xué)院:(學(xué)院, 地點(diǎn), 電話)。

            這樣的數(shù)據(jù)庫(kù)表是符合第三范式的,消除了數(shù)據(jù)冗余、更新異常、插入異常和刪除異常。

            鮑依斯-科得范式(BCNF):在第三范式的基礎(chǔ)上,數(shù)據(jù)庫(kù)表中如果不存在任何字段對(duì)任一候選關(guān)鍵字段的傳遞函數(shù)依賴則符合第三范式。

            假設(shè)倉(cāng)庫(kù)管理關(guān)系表為StorehouseManage(倉(cāng)庫(kù)ID, 存儲(chǔ)物品ID, 管理員ID, 數(shù)量),且有一個(gè)管理員只在一個(gè)倉(cāng)庫(kù)工作;一個(gè)倉(cāng)庫(kù)可以存儲(chǔ)多種物品。這個(gè)數(shù)據(jù)庫(kù)表中存在如下決定關(guān)系:

            (倉(cāng)庫(kù)ID, 存儲(chǔ)物品ID) →(管理員ID, 數(shù)量)

            (管理員ID, 存儲(chǔ)物品ID) → (倉(cāng)庫(kù)ID, 數(shù)量)

            所以,(倉(cāng)庫(kù)ID, 存儲(chǔ)物品ID)(管理員ID, 存儲(chǔ)物品ID)都是StorehouseManage的候選關(guān)鍵字,表中的唯一非關(guān)鍵字段為數(shù)量,它是符合第三范式的。但是,由于存在如下決定關(guān)系:

            (倉(cāng)庫(kù)ID) → (管理員ID)

            (管理員ID) → (倉(cāng)庫(kù)ID)

            即存在關(guān)鍵字段決定關(guān)鍵字段的情況,所以其不符合BCNF范式。它會(huì)出現(xiàn)如下異常情況:

            (1) 刪除異常:

            當(dāng)倉(cāng)庫(kù)被清空后,所有"存儲(chǔ)物品ID""數(shù)量"信息被刪除的同時(shí),"倉(cāng)庫(kù)ID""管理員ID"信息也被刪除了。

            (2) 插入異常:

            當(dāng)倉(cāng)庫(kù)沒(méi)有存儲(chǔ)任何物品時(shí),無(wú)法給倉(cāng)庫(kù)分配管理員。

            (3) 更新異常:

            如果倉(cāng)庫(kù)換了管理員,則表中所有行的管理員ID都要修改。

            把倉(cāng)庫(kù)管理關(guān)系表分解為二個(gè)關(guān)系表:

            倉(cāng)庫(kù)管理:StorehouseManage(倉(cāng)庫(kù)ID, 管理員ID);

            倉(cāng)庫(kù):Storehouse(倉(cāng)庫(kù)ID, 存儲(chǔ)物品ID, 數(shù)量)。

            這樣的數(shù)據(jù)庫(kù)表是符合BCNF范式的,消除了刪除異常、插入異常和更新異常。

          范式應(yīng)用

            我們來(lái)逐步搞定一個(gè)論壇的數(shù)據(jù)庫(kù),有如下信息:

           ?。?span lang="EN-US">1
          ) 用戶:用戶名,email,主頁(yè),電話,聯(lián)系地址

           ?。?span lang="EN-US">2) 帖子:發(fā)帖標(biāo)題,發(fā)帖內(nèi)容,回復(fù)標(biāo)題,回復(fù)內(nèi)容

            第一次我們將數(shù)據(jù)庫(kù)設(shè)計(jì)為僅僅存在表:
            

          用戶名

          email

          主頁(yè)

          電話

          聯(lián)系地址

          發(fā)帖標(biāo)題

          發(fā)帖內(nèi)容

          回復(fù)標(biāo)題

          回復(fù)內(nèi)容


            這個(gè)數(shù)據(jù)庫(kù)表符合第一范式,但是沒(méi)有任何一組候選關(guān)鍵字能決定數(shù)據(jù)庫(kù)表的整行,唯一的關(guān)鍵字段用戶名也不能完全決定整個(gè)元組。我們需要增加"發(fā)帖ID""回復(fù)ID"字段,即將表修改為:

          用戶名

          email

          主頁(yè)

          電話

          聯(lián)系地址

          發(fā)帖ID

          發(fā)帖標(biāo)題

          發(fā)帖內(nèi)容

          回復(fù)ID

          回復(fù)標(biāo)題

          回復(fù)內(nèi)容


            這樣數(shù)據(jù)表中的關(guān)鍵字(用戶名,發(fā)帖ID,回復(fù)ID)能決定整行:

            (用戶名,發(fā)帖ID,回復(fù)ID) → (email,主頁(yè),電話,聯(lián)系地址,發(fā)帖標(biāo)題,發(fā)帖內(nèi)容,回復(fù)標(biāo)題,回復(fù)內(nèi)容)

            但是,這樣的設(shè)計(jì)不符合第二范式,因?yàn)榇嬖谌缦聸Q定關(guān)系:

            (用戶名) → (email,主頁(yè),電話,聯(lián)系地址)

            (發(fā)帖ID) → (發(fā)帖標(biāo)題,發(fā)帖內(nèi)容)

            (回復(fù)ID) → (回復(fù)標(biāo)題,回復(fù)內(nèi)容)

            即非關(guān)鍵字段部分函數(shù)依賴于候選關(guān)鍵字段,很明顯,這個(gè)設(shè)計(jì)會(huì)導(dǎo)致大量的數(shù)據(jù)冗余和操作異常。

            我們將數(shù)據(jù)庫(kù)表分解為(帶下劃線的為關(guān)鍵字):

           ?。?span lang="EN-US">1
          ) 用戶信息:用戶名,email,主頁(yè),電話,聯(lián)系地址

           ?。?span lang="EN-US">2) 帖子信息:發(fā)帖ID,標(biāo)題,內(nèi)容

           ?。?span lang="EN-US">3) 回復(fù)信息:回復(fù)ID,標(biāo)題,內(nèi)容

           ?。?span lang="EN-US">4) 發(fā)貼:用戶名,發(fā)帖ID

           ?。?span lang="EN-US">5) 回復(fù):發(fā)帖ID,回復(fù)ID

            這樣的設(shè)計(jì)是滿足第1、2、3范式和BCNF范式要求的,但是這樣的設(shè)計(jì)是不是最好的呢?

            不一定。

             觀察可知,第4項(xiàng)"發(fā)帖"中的"用戶名""發(fā)帖ID"之間是1N的關(guān)系,因此我們可以把"發(fā)帖"合并到第2項(xiàng)的"帖子信息"中;第5項(xiàng)"回復(fù)"中的 "發(fā)帖ID""回復(fù)ID"之間也是1N的關(guān)系,因此我們可以把"回復(fù)"合并到第3項(xiàng)的"回復(fù)信息"中。這樣可以一定量地減少數(shù)據(jù)冗余,新的設(shè)計(jì)為:

            (1) 用戶信息:用戶名,email,主頁(yè),電話,聯(lián)系地址

           ?。?span lang="EN-US">2) 帖子信息:用戶名,發(fā)帖ID,標(biāo)題,內(nèi)容

           ?。?span lang="EN-US">3) 回復(fù)信息:發(fā)帖ID,回復(fù)ID,標(biāo)題,內(nèi)容

            數(shù)據(jù)庫(kù)表1顯然滿足所有范式的要求;

            數(shù)據(jù)庫(kù)表2中存在非關(guān)鍵字段"標(biāo)題"、"內(nèi)容"對(duì)關(guān)鍵字段"發(fā)帖ID"的部分函數(shù)依賴,即不滿足第二范式的要求,但是這一設(shè)計(jì)并不會(huì)導(dǎo)致數(shù)據(jù)冗余和操作異常;

            數(shù)據(jù)庫(kù)表3中也存在非關(guān)鍵字段"標(biāo)題"、"內(nèi)容"對(duì)關(guān)鍵字段"回復(fù)ID"的部分函數(shù)依賴,也不滿足第二范式的要求,但是與數(shù)據(jù)庫(kù)表2相似,這一設(shè)計(jì)也不會(huì)導(dǎo)致數(shù)據(jù)冗余和操作異常。

            由此可以看出,并不一定要強(qiáng)行滿足范式的要求,對(duì)于1N關(guān)系,當(dāng)1的一邊合并到N的那邊后,N的那邊就不再滿足第二范式了,但是這種設(shè)計(jì)反而比較好!

            對(duì)于MN的關(guān)系,不能將M一邊或N一邊合并到另一邊去,這樣會(huì)導(dǎo)致不符合范式要求,同時(shí)導(dǎo)致操作異常和數(shù)據(jù)冗余。
          對(duì)于11的關(guān)系,我們可以將左邊的1或者右邊的1合并到另一邊去,設(shè)計(jì)導(dǎo)致不符合范式要求,但是并不會(huì)導(dǎo)致操作異常和數(shù)據(jù)冗余。

            結(jié)論

            滿足范式要求的數(shù)據(jù)庫(kù)設(shè)計(jì)是結(jié)構(gòu)清晰的,同時(shí)可避免數(shù)據(jù)冗余和操作異常。這并意味著不符合范式要求的設(shè)計(jì)一定是錯(cuò)誤的,在數(shù)據(jù)庫(kù)表中存在111N關(guān)系這種較特殊的情況下,合并導(dǎo)致的不符合范式要求反而是合理的。

            在我們?cè)O(shè)計(jì)數(shù)據(jù)庫(kù)的時(shí)候,一定要時(shí)刻考慮范式的要求。

          posted @ 2005-12-20 10:54 DenisLing 閱讀(1814) | 評(píng)論 (3)編輯 收藏

          對(duì)spring事務(wù)類型詳解的一點(diǎn)補(bǔ)充(關(guān)于嵌套事務(wù))

               摘要: 可能大家對(duì)PROPAGATION_NESTED還不怎么了解,覺(jué)得有必要再補(bǔ)充一下^_^!  閱讀全文

          posted @ 2005-12-19 16:02 DenisLing 閱讀(3223) | 評(píng)論 (5)編輯 收藏

          Spring事務(wù)類型祥解

               摘要: 大家可能在spring中經(jīng)??吹竭@樣的定義:


          PROPAGATION_REQUIRED,readOnlyPROPAGATION_REQUIRED

          估計(jì)有好多朋友還沒(méi)有弄清楚里面的值的意思,仔細(xì)看完下面應(yīng)該知道自己什么情況下面應(yīng)該使用什么樣的聲明。^_^  閱讀全文

          posted @ 2005-12-18 16:30 DenisLing 閱讀(9634) | 評(píng)論 (2)編輯 收藏

          spring聲明式事務(wù)管理祥述

          Spring也提供了聲明式事務(wù)管理。這是通過(guò)Spring AOP實(shí)現(xiàn)的。

          Spring 中進(jìn)行事務(wù)管理的通常方式是利用AOP(面向切片編程)的方式,為普通java類封裝事務(wù)控制,它是通過(guò)動(dòng)態(tài)代理實(shí)現(xiàn)的,由于接口是延遲實(shí)例化的, spring在這段時(shí)間內(nèi)通過(guò)攔截器,加載事務(wù)切片。原理就是這樣,具體細(xì)節(jié)請(qǐng)參考jdk中有關(guān)動(dòng)態(tài)代理的文檔。本文主要講解如何在spring中進(jìn)行事 務(wù)控制。
          動(dòng)態(tài)代理的一個(gè)重要特征是,它是針對(duì)接口的,所以我們的dao要通過(guò)動(dòng)態(tài)代理來(lái)讓spring接管事務(wù),就必須在dao前面抽象出一個(gè)接口,當(dāng)然如果沒(méi)有這樣的接口,那么spring會(huì)使用CGLIB來(lái)解決問(wèn)題,但這不是spring推薦的方式,所以不做討論.

          大多數(shù)Spring用戶選擇聲明式事務(wù)管理。這是最少影響應(yīng)用代碼的選擇, 因而這是和非侵入性的輕量級(jí)容器的觀念是一致的。

          從考慮EJB CMT和Spring聲明式事務(wù)管理的相似以及不同之處出發(fā)是很有益的。 它們的基本方法是相似的:都可以指定事務(wù)管理到單獨(dú)的方法;如果需要可以在事務(wù)上 下文調(diào)用setRollbackOnly()方法。不同之處如下:

          • 不象EJB CMT綁定在JTA上,Spring聲明式事務(wù)管理可以在任何環(huán)境下使用。 只需更改配置文件,它就可以和JDBC、JDO、Hibernate或其他的事務(wù)機(jī)制一起工作

          • Spring可以使聲明式事務(wù)管理應(yīng)用到普通Java對(duì)象,不僅僅是特殊的類,如EJB

          • Spring提供聲明式回滾規(guī)則:EJB沒(méi)有對(duì)應(yīng)的特性, 我們將在下面討論這個(gè)特性?;貪L可以聲明式控制,不僅僅是編程式的

          • Spring允許你通過(guò)AOP定制事務(wù)行為。例如,如果需要,你可以在事務(wù) 回滾中插入定制的行為。你也可以增加任意的通知,就象事務(wù)通知一樣。使用 EJB CMT,除了使用setRollbackOnly(),你沒(méi)有辦法能 夠影響容器的事務(wù)管理

          • Spring不提供高端應(yīng)用服務(wù)器提供的跨越遠(yuǎn)程調(diào)用的事務(wù)上下文傳播。如 果你需要這些特性,我們推薦你使用EJB。然而,不要輕易使用這些特性。通常我 們并不希望事務(wù)跨越遠(yuǎn)程調(diào)用

          回滾規(guī)則的概念是很重要的:它們使得我們可以指定哪些異常應(yīng)該發(fā)起自 動(dòng)回滾。我們?cè)谂渲梦募校皇荍ava代碼中,以聲明的方式指定。因此,雖然我們?nèi)?然可以編程調(diào)用TransactionStatus對(duì)象的 setRollbackOnly()方法來(lái)回滾當(dāng)前事務(wù),多數(shù)時(shí)候我們可以 指定規(guī)則,如MyApplicationException應(yīng)該導(dǎo)致回滾。 這有顯著的優(yōu)點(diǎn),業(yè)務(wù)對(duì)象不需要依賴事務(wù)基礎(chǔ)設(shè)施。例如,它們通常不需要引 入任何Spring API,事務(wù)或其他任何東西。

          EJB的默認(rèn)行為是遇到系統(tǒng)異常(通常是運(yùn)行時(shí)異常), EJB容器自動(dòng)回滾事務(wù)。EJB CMT遇到應(yīng)用程序異常 (除了java.rmi.RemoteException外的checked異常)時(shí)不 會(huì)自動(dòng)回滾事務(wù)。雖然Spring聲明式事務(wù)管理沿用EJB的約定(遇到unchecked 異常自動(dòng)回滾事務(wù)),但是這是可以定制的。

          按照我們的測(cè)試,Spring聲明式事務(wù)管理的性能要?jiǎng)龠^(guò)EJB CMT。

          通 常通過(guò)TransactionProxyFactoryBean設(shè)置Spring事務(wù)代理。我們需 要一個(gè)目標(biāo)對(duì)象包裝在事務(wù)代理中。這個(gè)目標(biāo)對(duì)象一般是一個(gè)普通Java對(duì)象的bean。當(dāng)我 們定義TransactionProxyFactoryBean時(shí),必須提供一個(gè)相關(guān)的 PlatformTransactionManager的引用和事務(wù)屬性。 事務(wù)屬性含有上面描述的事務(wù)定義。

          <bean id="petStore" 
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          <property name="transactionManager"><ref bean="transactionManager"/></property>
          <property name="target"><ref bean="petStoreTarget"/></property>
          <property name="transactionAttributes">
          <props>
          <prop key="insert*">PROPAGATION_REQUIRED,-MyCheckedException</prop>
          <prop key="update*">PROPAGATION_REQUIRED</prop>
          <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
          </props>
          </property>
          </bean>

          事 務(wù)代理會(huì)實(shí)現(xiàn)目標(biāo)對(duì)象的接口:這里是id為petStoreTarget的bean。(使用 CGLIB也可以實(shí)現(xiàn)具體類的代理。只要設(shè)置proxyTargetClass屬性為true就可以。 如果目標(biāo)對(duì)象沒(méi)有實(shí)現(xiàn)任何接口,這將自動(dòng)設(shè)置該屬性為true。通常,我們希望面向接口而不是 類編程。)使用proxyInterfaces屬性來(lái)限定事務(wù)代理來(lái)代 理指定接口也是可以的(一般來(lái)說(shuō)是個(gè)好想法)。也可以通過(guò)從 org.springframework.aop.framework.ProxyConfig繼承或所有AOP代理工廠共享 的屬性來(lái)定制TransactionProxyFactoryBean的行為。

          這里的transactionAttributes屬性定義在 org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource 中的屬性格式來(lái)設(shè)置。這個(gè)包括通配符的方法名稱映射是很直觀的。注意 insert*的映射的值包括回滾規(guī)則。添加的-MyCheckedException 指定如果方法拋出MyCheckedException或它的子類,事務(wù)將 會(huì)自動(dòng)回滾??梢杂枚禾?hào)分隔定義多個(gè)回滾規(guī)則。-前綴強(qiáng)制回滾,+前綴指定提交(這允許即使拋出unchecked異常時(shí)也可以提交事務(wù),當(dāng)然你自己要明白自己 在做什么)。

          TransactionProxyFactoryBean允許你通過(guò) “preInterceptors”和“postInterceptors”屬性設(shè)置“前”或“后”通知來(lái)提供額外的 攔截行為??梢栽O(shè)置任意數(shù)量的“前”和“后”通知,它們的類型可以是 Advisor(可以包含一個(gè)切入點(diǎn)), MethodInterceptor或被當(dāng)前Spring配置支持的通知類型 (例如ThrowAdviceAfterReturningtAdviceBeforeAdvice, 這些都是默認(rèn)支持的)。這些通知必須支持實(shí)例共享模式。如果你需要高級(jí)AOP特 性來(lái)使用事務(wù),如有狀態(tài)的maxin,那最好使用通用的 org.springframework.aop.framework.ProxyFactoryBean, 而不是TransactionProxyFactoryBean實(shí)用代理創(chuàng)建者。

          也可以設(shè)置自動(dòng)代理:配置AOP框架,不需要單獨(dú)的代理定義類就可以生成類的 代理。

          附兩個(gè)spring的事務(wù)配置例子:
          <prop key="add">
               PROPAGATION_REQUIRES_NEW, -MyException
          </prop>
          注:上面的意思是add方法將獨(dú)占一個(gè)事務(wù),當(dāng)事務(wù)處理過(guò)程中產(chǎn)生MyException異?;蛘咴摦惓5淖宇悓⒒貪L該事務(wù)。

          <prop key="loadAll">
              PROPAGATION_SUPPORTS, ISOLATION_READ_COMMITED, Readonly
          </prop>
          注:表示loadAll方法支持事務(wù),而且不會(huì)讀取沒(méi)有提交事務(wù)的數(shù)據(jù)。它的數(shù)據(jù)為只讀(這樣有助于提高讀取的性能)

          附A Spring中的所有事務(wù)策略

          PROPAGATION_MANDATORY
          PROPAGATION_NESTED
          PROPAGATION_NEVER
          PROPAGATION_NOT_SUPPORTED
          PROPAGATION_REQUIRED
          PROPAGATION_REQUIRED_NEW
          PROPAGATION_SUPPORTS

          附B Spring中所有的隔離策略:

          ISOLATION_DEFAULT
          ISOLATION_READ_UNCOMMITED
          ISOLATION_COMMITED
          ISOLATION_REPEATABLE_READ
          ISOLATION_SERIALIZABLE

          posted @ 2005-12-01 11:47 DenisLing 閱讀(15362) | 評(píng)論 (0)編輯 收藏

          主站蜘蛛池模板: 广灵县| 当雄县| 海阳市| 慈利县| 平湖市| 弥勒县| 满洲里市| 绥德县| 青龙| 乌审旗| 平湖市| 仪陇县| 垫江县| 永靖县| 墨竹工卡县| 盖州市| 时尚| 伊金霍洛旗| 长春市| 永春县| 闽侯县| 乾安县| 克拉玛依市| 彭阳县| 淅川县| 孙吴县| 绵阳市| 蓬莱市| 米脂县| 龙海市| 镇巴县| 井陉县| 平顶山市| 霍州市| 湘潭市| 昭觉县| 千阳县| 衡水市| 辽中县| 土默特右旗| 通化市|