新聞中心
JDBC分布式事務(wù)淺析
作者:詩(shī)劍書生 2009-06-19 15:28:31
開發(fā)
后端
分布式 本文向您介紹JDB分布式事務(wù),作者首先介紹J2EE平臺(tái)的數(shù)據(jù)源的整體構(gòu),由此逐層剖析JDBC的分布式事務(wù)。

創(chuàng)新互聯(lián)建站是專業(yè)的沙河口網(wǎng)站建設(shè)公司,沙河口接單;提供成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行沙河口網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
在沒有開始JDBC分布式事務(wù)前,先來(lái)回顧一下J2EE平臺(tái)的數(shù)據(jù)源的整體構(gòu)加:
在上面的介紹中,可能大家會(huì)過(guò)于限入理解如何實(shí)現(xiàn)ConnectionPoolDataSource和PooledConnection,而忘記了它的整體結(jié)構(gòu).為了幫助大家更快地理解,我從以下幾點(diǎn)進(jìn)行總結(jié).
聲明:本文完全是作者根據(jù)SUN的文檔從實(shí)踐中總結(jié),沒有參考(事實(shí)上目前我還沒有找到這方面的參考)任何文章:
1.DataSource和ConnectionPoolDataSource的關(guān)系:
Sun的文檔中只對(duì)ConnectionPoolDataSource接口作了一般性規(guī)定,說(shuō)明它是PooledConnection的工廠,即ConnectionPoolDataSource是傳統(tǒng)的連結(jié)池角色,它負(fù)責(zé)產(chǎn)生物理連結(jié)PooledConnection.而PooledConnection又是Connectio的工廠,一個(gè)PooledConnection對(duì)象負(fù)責(zé)產(chǎn)生多個(gè)Connection對(duì)象供應(yīng)用程序調(diào)用.
而DataSource是對(duì)上面兩個(gè)過(guò)程的包裝,在DataSource中不僅要實(shí)現(xiàn)傳統(tǒng)連結(jié)池ConnectionPoolDataSource來(lái)產(chǎn)生物理連結(jié)PooledConnection,還要實(shí)現(xiàn)通過(guò)每個(gè)PooledConnection工廠來(lái)產(chǎn)生Connection,最后DataSource通過(guò)公開方法返回給調(diào)用者的是經(jīng)過(guò)兩次工廠出來(lái)的Connection.如果我們先不考慮JDBC分布式事務(wù),只看下圖左邊,就是說(shuō)工廠ConnectionPoolDataSource生成PooledConntion,二級(jí)工廠PooledConntion生產(chǎn)Connection,這兩個(gè)過(guò)程由DataSource在內(nèi)部包裝,只提供最后的產(chǎn)品Connection.
2.DataSource是服務(wù)端數(shù)據(jù)源,而傳統(tǒng)的連結(jié)池是客戶端數(shù)據(jù)源:
傳統(tǒng)的連結(jié)池要調(diào)用者生成這個(gè)連池的實(shí)例,完成初如化,這樣一個(gè)數(shù)據(jù)庫(kù)為了防止連結(jié)池的實(shí)例生成無(wú)限多個(gè)物理連結(jié),就要對(duì)保存物理連結(jié)的數(shù)據(jù)結(jié)構(gòu)進(jìn)行靜態(tài)定義,否則,你在你的程序中生成一個(gè)連結(jié)池對(duì)象,它生成30個(gè)物理連結(jié),我又在我的程序中生成連結(jié)池實(shí)例,又生成30個(gè)物理連結(jié),那就無(wú)法控制了,所以保存這30個(gè)物理連結(jié)的數(shù)據(jù)結(jié)構(gòu)必須是靜態(tài)的.
而DataSource同一個(gè)對(duì)象初始化后,對(duì)象被綁定到j(luò)ndi服務(wù)器上,通過(guò)jdni得到的是它的代碼存根,其中只包含Connection,而物理連結(jié)是不可能序列化的,所以不會(huì)被重新生成,調(diào)用者通過(guò)Connection對(duì)象作為參數(shù)傳給服務(wù)端,由它來(lái)操作實(shí)際的物理連結(jié).
思考一下:如果不考慮性能問(wèn)題,我是否可以把PooledConnction不再二次工廠化,只把PooledConntion作為Connection作為DataSource產(chǎn)品返回給調(diào)用者?
答案是不可以,因?yàn)槲锢磉B結(jié)不能序列化,也就是無(wú)法進(jìn)行分布式引用.二次工廠化不僅解決了性能的問(wèn)題,也同時(shí)解決了JDBC分布式事物調(diào)用的問(wèn)題.
3.為什么說(shuō)二次工廠化增加性能?
對(duì)于產(chǎn)生物理連結(jié),沒有什么區(qū)別,但物理連結(jié)本身并沒有滿負(fù)載工作,也就是一個(gè)物理Connection(TMD,我現(xiàn)在也不好說(shuō)Connection還是PooledConnectio,以前的Connection就是DataSource中的PooledConnection)其實(shí)可以同時(shí)綁定更多的Statement,而如果它直接給調(diào)用者調(diào)用了,句柄就被調(diào)用者拿去了,在調(diào)用者沒有返回時(shí)別的Statement沒法和它進(jìn)行”聯(lián)系”.而二次工廠的目的就是把多人的Statement通過(guò)”新的引用Connection”和物理連結(jié)綁定,使它更好地工作.
舉個(gè)例子,汽車這種東西,在目前的中國(guó)還是很昂貴的,作為客戶(調(diào)用者)我有幾件貨物要運(yùn),但一輛汽車(物理連結(jié))如果我一用,別人就不能用了.(傳統(tǒng)連結(jié)池和連結(jié)),盡管它還可以裝更多的貨物,現(xiàn)在汽車公司只能你一個(gè)車號(hào)(新的Connection),不給你實(shí)際的汽車,你只要把你的幾件東西只交給這個(gè)車號(hào),而其他人也可能同時(shí)把幾件東西交給這個(gè)車號(hào),最盡有更多的貨物因?yàn)槭褂猛卉囂?hào)而使那個(gè)物理汽車裝載了更多的貨物,當(dāng)然如果它滿了的話會(huì)產(chǎn)生另一輛車,如果生產(chǎn)的輛達(dá)到規(guī)定的數(shù)目你只好等等了,但這樣把多個(gè)客戶的貨物和同一車號(hào)關(guān)聯(lián)使汽車能更多地處理事務(wù),明顯地增加了性能.
理解了以上的結(jié)構(gòu),我們就不難理解javax.sql對(duì)分布式事務(wù)的支持,當(dāng)然,如果你對(duì)事務(wù)本身還不理解,那我就沒辦法讓你理解以下的知識(shí),因?yàn)槲也豢赡茉偻O聛?lái)講什么是事務(wù).它是和JDBC相同級(jí)別的內(nèi)容,也許在別的地方我會(huì)再講.
從上面的結(jié)構(gòu)中右邊看到,在DataSource中,其實(shí)封裝了兩種工廠,這兩種工廠都是兩層次的,其實(shí)XADataSource的作用和ConnectioPooledDataSource一樣,都是產(chǎn)生物理連結(jié)的,只不過(guò)它產(chǎn)生支持分布式事務(wù)的物理連結(jié)XAConnectio而已,(以后記住,凡以XA命名的類都是支持JDBC分布式事務(wù)的標(biāo)記.)我們看到,XAConnection中g(shù)etConnection()出來(lái)的連結(jié)和PooledConnection中g(shù)etConnection()出來(lái)的連結(jié)沒有區(qū)別,而Connection是DataSource的最終產(chǎn)品,這意味作什么?
這意味著支持分布式事務(wù)的過(guò)程由DataSource來(lái)做,你要操作的Connection和平時(shí)沒有兩樣,你只要聲明事務(wù)的開始和事務(wù)提交就行了!要使你的連結(jié)支持JDBC分布式事務(wù),你要在DataSource的配置中指明type是XADataSource就行了.然后申請(qǐng)一個(gè)一務(wù)(為了說(shuō)明方便省略了
- try{}catch(){})
- UserTransaction ut = ...........;
- ut.begin();
- Connection con1 = .........;
- Connection con2 = .........;
- Connection con3 = .........;
- if(條件) ut.setRollbackOnly();
- con1.close();
- con2.close();
- con3.close();
考察一下,為什么XADataSource類型的物理工廠會(huì)產(chǎn)生的連結(jié)可以直接被事務(wù)管理呢?其實(shí)這就是封裝的好處了,在XADataSource產(chǎn)生XAConnection時(shí),這個(gè)XAConnection實(shí)際是PooledConnection的子類,它擴(kuò)展了一個(gè)getXAResource() 方法,事務(wù)通過(guò)這個(gè)方法把它加入到事務(wù)容器中進(jìn)行管理.對(duì)于調(diào)用者來(lái)說(shuō),根本看不到事務(wù)是如果管理的,你只要聲明開始事務(wù),告訴容器我下面的操作要求事務(wù)參與了,最后告訴事務(wù)說(shuō)到這兒可以提交或回滾了,別的都是黑箱操作,不要你來(lái)做.
當(dāng)然如果沒有分布式事務(wù)的需求,雖然XADataSource可以用于本地事務(wù),但它要做很多資源測(cè)試,是一種浪費(fèi).
最后要說(shuō)明的是,既然你把操作交給事務(wù)來(lái)做,你就要對(duì)他放心,事務(wù)邊界由容器管理,你只在最后確定是提交還是回滾還是強(qiáng)行回滾setRollbackOnly()(強(qiáng)行回滾后不可以再提交).你不要在事務(wù)中調(diào)用某一連結(jié)的rollback,commit,也不能把Connection設(shè)為自動(dòng)提交,一般來(lái)說(shuō)當(dāng)你聲明為支持JDBC分布式事務(wù)的DataSource時(shí),創(chuàng)建的連結(jié)默認(rèn)都是關(guān)閉自動(dòng)提交的,只是你自己不要打開它.
因?yàn)镾UN的文檔只對(duì)DataSource接口作了一般規(guī)定,并沒有規(guī)定具體算法,所以我們?cè)谇宄厦娴慕Y(jié)構(gòu)后,可以實(shí)現(xiàn)不依賴容器的DataSource(其實(shí)只是它的思想.因?yàn)槟銓懗鰜?lái)的不依賴容器的DataSource)已經(jīng)不是這個(gè)意義上的DataSource了.它不能綁定到服務(wù)器上讓遠(yuǎn)程引用,所以生成物理連結(jié)的工廠應(yīng)該是靜態(tài)的,而物理連結(jié)這種產(chǎn)品也應(yīng)該是靜態(tài)的.然后再生成多個(gè)引用連結(jié).但這好象沒有多大意義,因?yàn)榧兛蛻舳塑浖话銇?lái)說(shuō)不可能同時(shí)有上萬(wàn)個(gè)客戶在線訪問(wèn)的,根本用不著這么費(fèi)事地實(shí)現(xiàn)連結(jié)池.
【編輯推薦】
- 簡(jiǎn)述Spring JDBC的學(xué)習(xí)
- J2EE技術(shù)之JDBC連接數(shù)據(jù)庫(kù)的各種寫法
- JBoss JDBC驅(qū)動(dòng)報(bào)錯(cuò)問(wèn)題分析與解決
- JavaBean中使用JDBC方式進(jìn)行事務(wù)處理
- JDBC與JSP簡(jiǎn)單模擬MVC三層架構(gòu)
分享題目:JDBC分布式事務(wù)淺析
當(dāng)前URL:http://www.dlmjj.cn/article/cdejoje.html


咨詢
建站咨詢
