<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    paulwong

    #

    給開(kāi)發(fā)維護(hù)大型項(xiàng)目開(kāi)發(fā)者的建議

    假設(shè)你是正在開(kāi)發(fā)和維護(hù)一個(gè)包含2000個(gè)類并使用了很多框架的Java開(kāi)發(fā)人員。你要如何理解這些代碼?在一個(gè)典型的Java企業(yè)項(xiàng)目小組中,大 部分能夠幫你的高級(jí)工程師看起來(lái)都很忙。文檔也很少。你需要盡快交付成果,并向項(xiàng)目組證明自己的能力。你會(huì)如何處理這種狀況?這篇文字為開(kāi)始一個(gè)新項(xiàng)目的 Java開(kāi)發(fā)者提供了一些建議。

    0. 不要試圖一下子搞懂整個(gè)項(xiàng)目
    好好考慮一下,為什么理解項(xiàng)目代碼是第一位的?大部分情況是你被要求修復(fù)一個(gè)bug或者加強(qiáng)系統(tǒng)已有功能。你要做的第一件事情不是理解整個(gè)項(xiàng)目的架構(gòu)。當(dāng)對(duì)項(xiàng)目進(jìn)行維護(hù)時(shí),這樣(理解整個(gè)項(xiàng)目架構(gòu))可能會(huì)對(duì)你造成巨大的壓力。

    即便是有著10年可靠編程經(jīng)驗(yàn)的Java開(kāi)發(fā)者可能也沒(méi)有理解項(xiàng)目的核心工作機(jī)制,盡管他們可能已經(jīng)在這個(gè)項(xiàng)目工作超過(guò)一年(假設(shè)他們并非原始開(kāi)發(fā)人員)。比如,對(duì)于認(rèn)證機(jī)制或事務(wù)管理機(jī)制。

    他們是怎么做的?他們對(duì)于自己負(fù)責(zé)的部分非常了解,并且能夠交付價(jià)值給小組。每天的交付價(jià)值遠(yuǎn)比了解一些以后還不確定有沒(méi)有的東西重要的多。

    1. 關(guān)注于盡快交付價(jià)值
    那我是否定了你對(duì)于項(xiàng)目架構(gòu)理解的熱情了么?完全不。我只是要求你盡早的交付價(jià)值,一旦你開(kāi)始一個(gè)項(xiàng)目,搭建了開(kāi)發(fā)環(huán)境,你就不應(yīng)該花一兩周時(shí)間才交付什么,無(wú)論他的規(guī)模大小。假如你是一個(gè)有經(jīng)驗(yàn)的程序員卻兩周都沒(méi)有任何交付,你的經(jīng)理怎么會(huì)知道你是真的在工作還是在看新聞。

    所以交付可以使大家都輕松起來(lái)。不要認(rèn)為你能夠做有價(jià)值的交付前必須理解整個(gè)項(xiàng)目。這是完全錯(cuò)誤的。加一段javascript的驗(yàn)證代碼對(duì)業(yè)務(wù)就很有價(jià)值,經(jīng)理能夠通過(guò)你的交付達(dá)到對(duì)你的信任。這樣能夠向上級(jí)領(lǐng)導(dǎo)證明你的貢獻(xiàn)以及員工價(jià)值。

    日復(fù)一日,在你不斷修復(fù)bug及增強(qiáng)功能之后,就能夠慢慢開(kāi)始理解項(xiàng)目架構(gòu)。不要低估對(duì)系統(tǒng)方方面面理解時(shí)需要花費(fèi)的時(shí)間。花3-4天理解認(rèn)證機(jī) 制,2-3天理解事物管理。這些都是依靠之前的相似項(xiàng)目的經(jīng)歷,但關(guān)鍵還是要花時(shí)間才能透徹的理解。要在日常工作中擠出時(shí)間,不要向經(jīng)理要求特定的時(shí)間來(lái)做這些。

    找找項(xiàng)目是否有一些不斷維護(hù)的單元測(cè)試用例。有效的單元測(cè)試用例是理解大型項(xiàng)目代碼的很好途徑。單元測(cè)試能夠幫助理解代碼片段,包括一個(gè)單元的外部接口(單元如何被調(diào)用以及返回內(nèi)容)及其內(nèi)部實(shí)現(xiàn)(調(diào)試單元測(cè)試比調(diào)試整個(gè)實(shí)際用例簡(jiǎn)單許多)。

    你如果能夠很好的理解一些內(nèi)容,寫(xiě)一些筆記,或者畫(huà)一些類圖、時(shí)序圖、數(shù)據(jù)模型圖,以便你或日后其他的開(kāi)發(fā)者維護(hù)。

    2. 維護(hù)大型項(xiàng)目所必須的技能
    你能從事當(dāng)前的工作,必然已經(jīng)具有良好的java技術(shù)。我們來(lái)談?wù)勀軌蜃屇阍谛马?xiàng)目中良好表現(xiàn)的其他技能。大部分時(shí)間,你在項(xiàng)目中的任務(wù)是修復(fù)bug和增強(qiáng)功能。

    有兩項(xiàng)很重要的技能能夠協(xié)助你維護(hù)大型項(xiàng)目代碼。

    2.1 能夠迅速發(fā)現(xiàn)需要的類
    在任何維護(hù)活動(dòng)中,無(wú)論是修復(fù)bug或增強(qiáng)功能,第一個(gè)動(dòng)作就是識(shí)別出當(dāng)前修復(fù)或增強(qiáng)的用例中調(diào)用的類。當(dāng)你定位到需要修復(fù)或增強(qiáng)的類/方法,就已經(jīng)完工了一半。

    2.2 能夠分析變更的影響
    當(dāng)你在完成必要的修改或增強(qiáng)工作后,最重要的就是要確認(rèn)你的修改沒(méi)有破壞代碼的其他部分。你要用你的java技術(shù)及對(duì)其他框架的理解找出變更可能影響的部分。下面有兩個(gè)簡(jiǎn)單的例子詳細(xì)描述了最后提及的情況:

    a)當(dāng)類A的equals()方法變更后,調(diào)用一個(gè)保護(hù)A實(shí)例的List的contains()方法時(shí)就會(huì)被影響到。若Java知識(shí)不夠,很難考慮到這樣的影響。

    b)在一個(gè)web項(xiàng)目中,我們假設(shè)“user id”保存在session中。一個(gè)新入程序員可能在“user id”中加入一些信息作為bug修復(fù)的方法,但是卻不知道會(huì)影響到那些關(guān)聯(lián)“user id”的用例。

    當(dāng)你提高了如上兩個(gè)技能,盡管你對(duì)項(xiàng)目不是非常了解,但大部分的維護(hù)任務(wù)會(huì)變得簡(jiǎn)單很多。若你修復(fù)一個(gè)bug,你會(huì)定位并修復(fù)這個(gè)bug,并且保證變更不會(huì)破壞項(xiàng)目的其他部分。若你增強(qiáng)或加入一個(gè)特性,基本上你只需要模仿現(xiàn)有的特性使用相似的設(shè)計(jì)。

    在一個(gè)在線銀行項(xiàng)目中,為什么“查看賬戶摘要”和“查看交易歷史”的設(shè)計(jì)需要巨大的差別呢?如果你理解了“查看賬戶摘要”的設(shè)計(jì),完全可以模仿開(kāi)發(fā)出“查看交易歷史”的功能。

    就修復(fù)bug和增強(qiáng)來(lái)說(shuō),你不必完全理解所有2000個(gè)類的工作內(nèi)容和代碼如何運(yùn)行來(lái)推動(dòng)系統(tǒng)。你若有上面的技能,就能很快定位需要修改的代碼的部分,使用良好的java和框架技能修復(fù),保證變更不會(huì)破壞項(xiàng)目的其他部分并交付,盡管你可能只知道一小部分項(xiàng)目的設(shè)計(jì)。

    3. 使用工具找到需要的變更內(nèi)容以及變更產(chǎn)生的影響
    繼續(xù)我們盡快交付的主題,你應(yīng)當(dāng)尋找那些能夠通過(guò)盡量少的了解項(xiàng)目但能幫助你盡快實(shí)施交付的工具作為輔助。

    3.1 迅速發(fā)現(xiàn)需要變更內(nèi)容的工具
    無(wú)論是修復(fù)bug還是系統(tǒng)增強(qiáng),首先都要找到該用例調(diào)用的你需要修改的類及方法。基本有兩種方式理解一個(gè)用例的工作方式,靜態(tài)代碼分析和運(yùn)行時(shí)分析。

    源碼分析統(tǒng)計(jì)掃描所有代碼并且展示類之間的關(guān)系。市場(chǎng)上有很多設(shè)備與工具。比如:Architexa, AgileJ, UModel, Poseidon等。

    所有的靜態(tài)代碼分析工具缺點(diǎn)在于無(wú)法確切展示用例中類或方法的運(yùn)行時(shí)調(diào)用情況。因此Java新加入了特性,如回調(diào)機(jī)制(callback patterns)。如靜態(tài)分析工具無(wú)法推斷出當(dāng)頁(yè)面提交按鈕被點(diǎn)擊時(shí)哪個(gè)Servlet被調(diào)用了。

    運(yùn)行時(shí)分析工具能夠展示類和方法在用例運(yùn)行時(shí)的狀態(tài)。工具包括:MaintainJ, Diver,jSonde,Java Call Tracer等。這些工具可以捕獲運(yùn)行時(shí)的堆棧狀態(tài),并以此為一個(gè)用例生成序列圖和類圖。

    序列圖展示了該用例在運(yùn)行時(shí)所有調(diào)用的方法。若你在修復(fù)一個(gè)bug,那這個(gè)bug很可能就是這些被調(diào)用的方法之一。
    若你在增強(qiáng)已有功能,利用序列圖理解調(diào)用流程然后再修改。可能是新增一個(gè)驗(yàn)證,修改DAO等。

    若你在新增功能,找到一些相似的特性,利用序列圖理解調(diào)用流程然后模仿開(kāi)發(fā)新功能。

    要小心挑選運(yùn)行時(shí)分析工具。信息過(guò)多是這類工具的主要問(wèn)題。選擇一些提供簡(jiǎn)單過(guò)濾無(wú)效信息并能夠方便的查看各種視圖的工具。

    3.2 迅速發(fā)現(xiàn)需要變更內(nèi)容的工具
    若單元測(cè)試有效,可以通過(guò)運(yùn)行單元測(cè)試發(fā)現(xiàn)變更有沒(méi)有破壞其他測(cè)試用例。有效維護(hù)并且覆蓋大型企業(yè)應(yīng)用的單元測(cè)試還是比較少的。下面有一些針對(duì)該情況的工具。

    仍然是有兩種技術(shù)靜態(tài)代碼分析和運(yùn)行時(shí)分析可以使用。市場(chǎng)中有很多靜態(tài)代碼分析工具可用。如:Lattix, Structure101, Coverity, nWire and IntelliJ’s DSM。

    給定一個(gè)變更后的類,上述工具均可識(shí)別對(duì)該類存在依賴的類的集合。開(kāi)發(fā)者需要根據(jù)這些信息“猜測(cè)”可能產(chǎn)生影響的用例,因?yàn)檫@些工具無(wú)法展示運(yùn)行時(shí)類之間的調(diào)用關(guān)系。

    市場(chǎng)上的可以用于運(yùn)行時(shí)影響分析的工具并不多,除了MaintainJ。MaintainJ先捕獲在一個(gè)用例中調(diào)用的所有類和方法。當(dāng)所有用例的上 述信息都被捕獲之后,就很容易發(fā)現(xiàn)類的變更對(duì)用例的影響。MaintainJ能夠有效工作的前置條件就是項(xiàng)目的所有用例都應(yīng)當(dāng)先運(yùn)行一遍,以便能夠獲得運(yùn) 行時(shí)的依賴關(guān)系。

    總之,目前你在迅速準(zhǔn)確分析變更影響方面,還是可以從工具中獲得有限的幫助。首先根據(jù)需要實(shí)施一些影響分析,然后根據(jù)自己或小組其他高級(jí)成員評(píng)審來(lái)判斷變更的影響。你可能需要上面提到的工具對(duì)你的判斷進(jìn)行反復(fù)確認(rèn)。

    4. 對(duì)上述內(nèi)容的兩個(gè)忠告
    4.1 不要降低代碼質(zhì)量
    為了快速交付,所以沒(méi)有全盤(pán)理解架構(gòu),但絕不能以降低代碼質(zhì)量為條件。下面是一些你可能因?yàn)橹豢紤]快速交付而引發(fā)的代碼質(zhì)量問(wèn)題。

    因?yàn)樾薷拇a涉及到很多的依賴,所以新增代碼相對(duì)而言風(fēng)險(xiǎn)較小。例如,有5個(gè)用例都調(diào)用了某個(gè)方法。為了改進(jìn)某個(gè)用例,你需要修改這個(gè)方法的實(shí)現(xiàn)。 最簡(jiǎn)單的做法就是復(fù)制這個(gè)方法,重命名,然后在改進(jìn)的用例中調(diào)用新方法。千萬(wàn)不要這么做。代碼冗余絕對(duì)是非常有害的。嘗試對(duì)方法進(jìn)行包裝或者重寫(xiě),甚至是 直接修改,然后重新測(cè)試所有用例,通常停下來(lái)想一想,然后親手去實(shí)施,是一個(gè)比較好的方式。
    code quality 
    ( 伯樂(lè)在線配圖)

    另一個(gè)例子是將“private”方法改為“public”,使得別的類也可以調(diào)用。盡量不要將非必須的部分暴露出來(lái)。假如為了更好的設(shè)計(jì)需要重構(gòu),就應(yīng)當(dāng)著手去做。

    大部分應(yīng)用都有確定的結(jié)構(gòu)和模式來(lái)實(shí)施。修復(fù)或增強(qiáng)程序時(shí),確認(rèn)你沒(méi)有偏離這樣的模式。若對(duì)約定不確定,請(qǐng)其他的高級(jí)開(kāi)發(fā)者來(lái)審核你的變更。若你必須做一些違背約定的實(shí)施,盡量放置于一個(gè)規(guī)模較小的類中(一個(gè)200行代碼的類中的私有函數(shù)應(yīng)當(dāng)不會(huì)影響應(yīng)用的整體設(shè)計(jì))

    4.2 不要停止深入理解項(xiàng)目架構(gòu)
    按照文章列出的方式,假設(shè)你能夠在對(duì)項(xiàng)目了解較少的情況下進(jìn)行交付并以此持續(xù)下去,可能你會(huì)停止對(duì)項(xiàng)目架構(gòu)的深入了解。這樣從長(zhǎng)遠(yuǎn)角度來(lái)說(shuō)對(duì)你的職 業(yè)生涯沒(méi)有幫助。當(dāng)你的經(jīng)驗(yàn)增加時(shí),你應(yīng)當(dāng)承擔(dān)比較大的模塊任務(wù)。如構(gòu)建一個(gè)完整的新特性或者修改項(xiàng)目的一些基礎(chǔ)設(shè)計(jì)等較大的改進(jìn)。當(dāng)你能夠做這些改進(jìn) 時(shí),你對(duì)項(xiàng)目的整體架構(gòu)應(yīng)該相當(dāng)了解。文中列舉的方法是讓你在最短的時(shí)間內(nèi)提升自己,而不是阻止你完整理解整個(gè)項(xiàng)目。

    5. 結(jié)論
    整篇文章集中在對(duì)項(xiàng)目進(jìn)行必要了解的前提下進(jìn)行快速交付。你可以在不降低代碼質(zhì)量的前提下這么做。
    若修復(fù)一個(gè)bug,迅速定位并修復(fù)。有必要可以使用運(yùn)行時(shí)分析工具。若新增一個(gè)特寫(xiě),可以尋找相似特寫(xiě),理解流程(有必要使用工具)并編寫(xiě)。

    或許這些聽(tīng)起來(lái)很簡(jiǎn)單,但是實(shí)用嗎?當(dāng)然。但前提是你有良好的java技術(shù)以及對(duì)框架足夠了解才能先修改代碼,然后對(duì)變更影響進(jìn)行分析。對(duì)變更影響的分析比實(shí)施變更需要更多的技巧。你可能需要高級(jí)開(kāi)發(fā)人員協(xié)助你分析變更影響。

    大約有50%的IT可操作預(yù)算用于簡(jiǎn)單的bug修復(fù)和功能增強(qiáng)。根據(jù)文中的建議,對(duì)于維護(hù)活動(dòng)中的經(jīng)費(fèi)的節(jié)省應(yīng)當(dāng)還是很有幫助的。

    作者 Choudary Kothapalli 也是 MaintainJ 項(xiàng)目的建立者。

    posted @ 2012-04-15 20:37 paulwong 閱讀(242) | 評(píng)論 (0)編輯 收藏

    轉(zhuǎn)一個(gè)J2EE開(kāi)發(fā)時(shí)的包命名規(guī)則,養(yǎng)成良好的開(kāi)發(fā)習(xí)慣

    代碼編寫(xiě)規(guī)范目的:能夠在編碼過(guò)程中實(shí)現(xiàn)規(guī)范化,為以后的程序開(kāi)發(fā)中養(yǎng)成良好的行為習(xí)慣。
    代碼編寫(xiě)規(guī)范使用范圍:J2EE項(xiàng)目開(kāi)發(fā)。
    包命名規(guī)范:
    目的:包的命名規(guī)范應(yīng)當(dāng)體現(xiàn)出項(xiàng)目資源良好的劃分

    servlet類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.servlet
    例如:net.linkcn.web.servlet

    自定義標(biāo)簽類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.tags
    例如:net.linkcn.web.tags

    過(guò)濾器類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.filter
    例如:net.linkcn.web.filter

    Action類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.struts.action
    例如:net.linkcn.web.struts.action

    ActionForm類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.struts.form
    例如:net.linkcn.web.struts.form

    Javabean所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.struts.service.impl
    例如:net.linkcn.web.service.impl

    Javabean實(shí)現(xiàn)接口命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.web.service
    例如:net.linkcn.web.service

    DAO類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.dao.impl
    例如:net.linkcn.dao.impl

    DAO類所實(shí)現(xiàn)的接口在包中命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.dao
    例如:net.linkcn.dao

    POJO類與hbm文件所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.dao.hbm
    例如:net.linkcn.dao.hbm

    全局公共類、接口類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.global
    例如:net.linkcn.global

    全局工具類所在包命名規(guī)范:公司名稱.開(kāi)發(fā)組名稱.項(xiàng)目名稱.util
    例如:net.linkcn.util

    類命名規(guī)范
    基本命名規(guī)范:

    類、接口命名

    命名規(guī)范:以大寫(xiě)字母開(kāi)頭,如果有多個(gè)單詞,每個(gè)單詞頭字母大寫(xiě)
    例如:StudentInfo
    接口命名

    命名規(guī)范:以大寫(xiě)字母"I"開(kāi)頭,如果有多個(gè)單詞,每個(gè)單詞頭字母大寫(xiě)
    例如:IStudentInfo

    接口實(shí)現(xiàn)類命名:
    命名規(guī)范:將實(shí)現(xiàn)的接口名稱的首字母"I"去掉,以"Impl作為結(jié)尾",如果有多個(gè)單詞,每個(gè)單詞頭字母大寫(xiě)。
    例如:StudentInfoImpl

    J2EE+SSH框架命名規(guī)范
    servlet類命名:
    命名規(guī)范:以Servlet單詞結(jié)尾
    例如:LoginServlet

    POJO命名:
    使用hibernate自動(dòng)生成的類即可

    DAO類命名:
    使用hibernate自動(dòng)生成的類即可

    Action類命名:
    命名規(guī)范:Action的命名以POJO名稱來(lái)制定,POJO名稱Action
    例如:
    一個(gè)POJO名稱為Diary,其對(duì)應(yīng)的action為DiaryAction

    ActionForm類命名:
    命名規(guī)范:ActionForm的命名以POJO名稱來(lái)制定,POJO名稱Form
    例如:
    一個(gè)POJO名稱為Diary,其對(duì)應(yīng)的actioForm為DiaryForm

    業(yè)務(wù)邏輯接口命名:
    命名規(guī)范:業(yè)務(wù)邏輯接口的命名以POJO名稱來(lái)制定,IPOJO名稱Service
    例如:
    一個(gè)POJO名稱為Diary,其對(duì)應(yīng)的業(yè)務(wù)邏輯接口為IDiaryService

    業(yè)務(wù)邏輯實(shí)現(xiàn)類命名:
    命名規(guī)范:業(yè)務(wù)邏輯接口實(shí)現(xiàn)類的命名以POJO名稱來(lái)制定
    例如:
    一個(gè)POJO名稱為Diary,對(duì)應(yīng)的業(yè)務(wù)邏輯接口實(shí)現(xiàn)類名為DiaryServiceImpl

    類變量命名:
    命名規(guī)范:變量名首字母必須小寫(xiě),如果該變量名有多個(gè)單詞組成,后面的單 詞首字母大寫(xiě),單詞與單詞之間不要使用"_"做連接,變量名訪問(wèn)控制必須為私有, 可以對(duì)其增加setter與getter方法。
    例如:
    private int studentAge;
    public int getStudentAge(){
    return studentAge;
    }
    public void setStudentAge(int studentAge) {
    this.studentAge=studentAge;
    }

    常量命名:
    命名規(guī)范:所有字母大寫(xiě),如果有多個(gè)單詞組成,單詞與單詞之間以” _“隔開(kāi)。而 且該變量必須是公共、靜態(tài)、final類型
    例如:public static final String USER_NAME=”userName“;

    方法命名
    命名規(guī)范:首字母必須小寫(xiě),如果該變量名有多個(gè)單詞組成,后面的單詞首字母 大寫(xiě),單詞與單詞之間不要使用"_"做連接。單詞不要使用名詞。
    例如:public int checkLogin(String name,String pwd){}

    注釋規(guī)范:注釋規(guī)范是整個(gè)開(kāi)發(fā)規(guī)范中最為重要的組成部分,必須嚴(yán)格執(zhí)行。

    類的注釋:
    作用:注釋整個(gè)類,簡(jiǎn)單概述該類作用。
    書(shū)寫(xiě)規(guī)范:類的注釋必須寫(xiě)在該類的聲明語(yǔ)法之前。在注釋中要描述該類的基 本作用,作者,日期,版本,公司名稱,版權(quán)聲明。
    格式:

    類的聲明語(yǔ)法

    例如:

    public class AdminDAO

    變量、常量注釋:
    作用:簡(jiǎn)單描述該變量的意義。
    書(shū)寫(xiě)規(guī)范:變量注釋必須寫(xiě)在變量定義之前,簡(jiǎn)單描述其代表的意義。
    格式:


    例如:


    public int age;
    方法注釋:
    作用:對(duì)該方法功能簡(jiǎn)單描述,其參數(shù)、返回值意義的注解。
    書(shū)寫(xiě)規(guī)范:方法注釋必須寫(xiě)在方法定義之前。該注釋包括:方法其功能的簡(jiǎn)單 描述,方法的參數(shù)、返回值類型、返回值意義簡(jiǎn)單的描述。
    格式:


    例如:

    public booleaneditAdminPassword(int adminId,String oldPassword,
    String password) throws UserException,ServiceException;

    Jsp頁(yè)面命名:
    命名規(guī)范:jsp頁(yè)面名稱要以小寫(xiě)字母開(kāi)頭,如果有多個(gè)單詞組成,后面的單詞以 大寫(xiě)字母開(kāi)頭。名稱要體現(xiàn)出該頁(yè)面的意義,最好能夠與模塊名稱聯(lián)系在一起。
    例如:
    login.jsp --登錄頁(yè)面
    register.jsp --注冊(cè)頁(yè)面
    message.jsp --客戶留言頁(yè)面

    J2EE項(xiàng)目工程文件夾組織規(guī)范:
    目的:規(guī)范學(xué)員web應(yīng)用程序的資源組織形式,形成良好的文件組織習(xí)慣。文件的組織形式應(yīng)當(dāng)體現(xiàn)模塊的劃分。

    根據(jù)eclipse工具的特征,項(xiàng)目的目錄結(jié)構(gòu)為:
    src
    ----存放java文件
    WebRoot
    |--images --存放web程序所需的公共圖片
    |--css --存放web程序所需的公共樣式表
    |--js --存放web程序所需的公共js文件
    |--commons --存放web程序所需的公共文件
    |--功能模塊文件夾(存放與某個(gè)功能模塊相關(guān)的資源)
    |--images --存放與該功能模塊相關(guān)的圖片
    |--css --存放與該模塊相關(guān)的樣式表文件
    |--js --存放與該模塊相關(guān)的js文件
    |--jsp、html頁(yè)面
    |--WEB-INF
    |--classes
    |--lib
    |--tld文件

    J2EE項(xiàng)目提交規(guī)范
    項(xiàng)目完成時(shí)要將項(xiàng)目作為一個(gè)產(chǎn)品交付用戶,良好的項(xiàng)目組織規(guī)范可以使用戶可以方便的找尋項(xiàng)目中需要的資源,同時(shí)也是一個(gè)公司專業(yè)性的體現(xiàn)。項(xiàng)目提交時(shí),要按照下列文件格式進(jìn)行提交。

    項(xiàng)目主文件夾:
    作用:存放項(xiàng)目其他資源文件。
    命名規(guī)范:時(shí)間_班級(jí)編號(hào)_第X小組。
    例如:070706_GS2T18_第四小組。
    項(xiàng)目主文件夾下面包括以下文件夾和文件:
    |--src:保存.java文件。
    |--database:保存數(shù)據(jù)庫(kù)的腳本文件或者數(shù)據(jù)庫(kù)備份文件。
    |--source:保存eclipse工程中WebRoot目錄下的所有文件。
    |--depend:保存編譯該程序必須依賴的其他jar文件。
    |--javadoc:保存所有類生成的javadoc api文檔。
    |--war:保存程序的歸檔文件
    |--xx.war:已經(jīng)打包好的工程文件,可以直接運(yùn)行。
    |--project:保存開(kāi)發(fā)項(xiàng)目原工程代碼及文件。
    |--產(chǎn)品說(shuō)明書(shū).doc:圖文方式展現(xiàn)該產(chǎn)品使用方法。
    |--build.xml:ant腳本,用于生成運(yùn)行的war文件。
    |--項(xiàng)目解說(shuō).ppt:進(jìn)行項(xiàng)目講解的ppt(ppt僅供在校模擬項(xiàng)目使用,不用于其他商業(yè)用途)
    注:一個(gè)完整的項(xiàng)目中,數(shù)據(jù)庫(kù)必須有一定量的有效的測(cè)試數(shù)據(jù)來(lái)支持該程序的運(yùn)行

    包的命名 
    Java包的名字都是由小寫(xiě)單詞組成。但是由于Java面向?qū)ο缶幊痰奶匦裕恳幻鸍ava程序員都可以編寫(xiě)屬于自己的Java包,為了保障每個(gè) Java包命名的唯一性,在最新的Java編程規(guī)范中,要求程序員在自己定義的包的名稱之前加上唯一的前綴。由于互聯(lián)網(wǎng)上的域名稱是不會(huì)重復(fù)的,所以程序 員一般采用自己在互聯(lián)網(wǎng)上的域名稱作為自己程序包的唯一前綴。
    例如: net.frontfree.javagroup

    類的命名
    類的名字必須由大寫(xiě)字母開(kāi)頭而單詞中的其他字母均為小寫(xiě);如果類名稱由多個(gè)單詞組成,則每個(gè)單詞的首字母均應(yīng)為大寫(xiě)例如TestPage;如果類名 稱中包含單詞縮寫(xiě),則這個(gè)所寫(xiě)詞的每個(gè)字母均應(yīng)大寫(xiě),如:XMLExample,還有一點(diǎn)命名技巧就是由于類是設(shè)計(jì)用來(lái)代表對(duì)象的,所以在命名類時(shí)應(yīng)盡量 選擇名詞。   
    例如: Circle

    方法的命名
    方法的名字的第一個(gè)單詞應(yīng)以小寫(xiě)字母作為開(kāi)頭,后面的單詞則用大寫(xiě)字母開(kāi)頭。
    例如: sendMessge

    常量的命名
    常量的名字應(yīng)該都使用大寫(xiě)字母,并且指出該常量完整含義。如果一個(gè)常量名稱由多個(gè)單詞組成,則應(yīng)該用下劃線來(lái)分割這些單詞。
    例如: MAX_VALUE

    參數(shù)的命名
    參數(shù)的命名規(guī)范和方法的命名規(guī)范相同,而且為了避免閱讀程序時(shí)造成迷惑,請(qǐng)?jiān)诒M量保證參數(shù)名稱為一個(gè)單詞的情況下使參數(shù)的命名盡可能明確。

    Javadoc注釋
    Java除了可以采用我們常見(jiàn)的注釋方式之外,Java語(yǔ)言規(guī)范還定義了一種特殊的注釋,也就是我們所說(shuō)的Javadoc注釋,它是用來(lái)記錄我們代 碼中的API的。Javadoc注釋是一種多行注釋,以結(jié)束,注釋可以包含一些HTML標(biāo)記符和專門(mén)的關(guān)鍵詞。使用Javadoc 注釋的好處是編寫(xiě)的注釋可以被自動(dòng)轉(zhuǎn)為在線文檔,省去了單獨(dú)編寫(xiě)程序文檔的麻煩。
    例如:

    在每個(gè)程序的最開(kāi)始部分,一般都用Javadoc注釋對(duì)程序的總體描述以及版權(quán)信息,之后在主程序中可以為每個(gè)類、接口、方法、字段添加 Javadoc注釋,每個(gè)注釋的開(kāi)頭部分先用一句話概括該類、接口、方法、字段所完成的功能,這句話應(yīng)單獨(dú)占據(jù)一行以突出其概括作用,在這句話后面可以跟 隨更加詳細(xì)的描述段落。在描述性段落之后還可以跟隨一些以Javadoc注釋標(biāo)簽開(kāi)頭的特殊段落,例如上面例子中的@auther和@version,這 些段落將在生成文檔中以特定方式顯示。

    變量和常量命名
    變量命名的方法采用匈牙利命名法,基本結(jié)構(gòu)為scope_typeVariableName,它使用3字符前綴來(lái)表示數(shù)據(jù)類型,3個(gè)字符的前綴必須 小寫(xiě),前綴后面是由表意性強(qiáng)的一個(gè)單詞或多個(gè)單詞組成的名字,而且每個(gè)單詞的首寫(xiě)字母大寫(xiě),其它字母小寫(xiě),這樣保證了對(duì)變量名能夠進(jìn)行正確的斷句。例如, 定義一個(gè)整形變量,用來(lái)記錄文檔數(shù)量:intDocCount,其中int表明數(shù)據(jù)類型,后面為表意的英文名,每個(gè)單詞首字母大寫(xiě)。這樣,在一個(gè)變量名就 可以反映出變量類型和變量所存儲(chǔ)的值的意義兩方面內(nèi)容,這使得代碼語(yǔ)句可讀性強(qiáng)、更加容易理解。byte、int、char、long、float、 double、boolean和short。
    變量類型和首字母對(duì)照關(guān)系如下表:
    數(shù)據(jù)類型/對(duì)象類型 / 變量前綴 / 備注
    byte bye
    char chr
    float flt
    boolean bln 做布爾變量時(shí),使用bln
    Integer/int int
    String str
    Single sng
    short sht
    Long/long lng
    Double/double dbl
    Currency cur
    Variant bln astr obj vnt 做布爾變量用時(shí),用bln,做字符串?dāng)?shù)組用時(shí),用astr,做為對(duì)象使用時(shí),用obj,不確定時(shí),用vnt。
    對(duì)于數(shù)組,在數(shù)據(jù)類型的前綴前再增加一個(gè)a,例如字符串?dāng)?shù)組為astr。對(duì)于在多個(gè)函數(shù)內(nèi)都要使用的全局變量,在前面再增加“g_”。例如一個(gè)全局的字符串變量:g_strUserInfo。

    在變量命名時(shí)要注意以下幾點(diǎn):
    · 選擇有意義的名字,注意每個(gè)單詞首字母要大寫(xiě)。

    · 在一段函數(shù)中不使用同一個(gè)變量表示前后意義不同的兩個(gè)數(shù)值。

    · i、j、k等只作為小型循環(huán)的循環(huán)索引變量。

    · 避免用Flag來(lái)命名狀態(tài)變量。

    · 用Is來(lái)命名邏輯變量,如:blnFileIsFound。通過(guò)這種給布爾變量肯定形式的命名方式,使得其它開(kāi)發(fā)人員能夠更為清楚
    的理解布爾變量所代表的意義。

    · 如果需要的話,在變量最后附加計(jì)算限定詞,如:curSalesSum。

    · 命名不相包含,curSales和curSalesSum。

    · Static Final 變量的名字應(yīng)該都大寫(xiě),并且指出完整含義。

    · 如果需要對(duì)變量名進(jìn)行縮寫(xiě)時(shí),一定要注意整個(gè)代碼中縮寫(xiě)規(guī)則的一致性。例如,如果在代碼的某些區(qū)域中使用intCnt,而在另一些區(qū)域中又使用intCount,就會(huì)給代碼增加不必要的復(fù)雜性。建議變量名中盡量不要出現(xiàn)縮寫(xiě)。

    · 通過(guò)在結(jié)尾處放置一個(gè)量詞,就可創(chuàng)建更加統(tǒng)一的變量,它們更容易理解,也更容易搜索。例如,請(qǐng)使用 strCustomerFirst和strCustomerLast,而不要使用strFirstCustomer和strLastCustomer。常 用的量詞后綴有:First(一組變量中的第一個(gè))、Last(一組變量中的最后一個(gè))、Next(一組變量中的下一個(gè)變量)、Prev(一組變量中的上 一個(gè))、Cur(一組變量中的當(dāng)前變量)。

    · 為每個(gè)變量選擇最佳的數(shù)據(jù)類型,這樣即能減少對(duì)內(nèi)存的需求量,加快代碼的執(zhí)行速度,又會(huì)降低出錯(cuò)的可能性。用于變量的數(shù)據(jù)類型可能會(huì)影響該變量進(jìn)行計(jì)算所產(chǎn)生的結(jié)果。在這種情況下,編譯器不會(huì)產(chǎn)生運(yùn)行期錯(cuò)誤,它只是迫使該值符合數(shù)據(jù)類型的要求。這類問(wèn)題極難查找。

    · 盡量縮小變量的作用域。如果變量的作用域大于它應(yīng)有的范圍,變量可繼續(xù)存在,并且在不再需要該變量后的很長(zhǎng)時(shí)間內(nèi)仍然占用資源。它們的主要問(wèn)題是,任何類 中的任何方法都能對(duì)它們進(jìn)行修改,并且很難跟蹤究竟是何處進(jìn)行修改的。占用資源是作用域涉及的一個(gè)重要問(wèn)題。對(duì)變量來(lái)說(shuō),盡量縮小作用域?qū)?huì)對(duì)應(yīng)用程序的 可靠性產(chǎn)生巨大的影響。
    關(guān)于常量的命名方法,在JAVA代碼中,無(wú)論什么時(shí)候,均提倡應(yīng)用常量取代數(shù)字、固定字符串。也就是說(shuō),程序中除0,1以外,盡量不應(yīng)該出現(xiàn)其他數(shù) 字。常量可以集中在程序開(kāi)始部分定義或者更寬的作用域內(nèi),名字應(yīng)該都使用大寫(xiě)字母,并且指出該常量完整含義。如果一個(gè)常量名稱由多個(gè)單詞組成,則應(yīng)該用下 劃線“_”來(lái)分割這些單詞如:NUM_DAYS_IN_WEEK、MAX_VALUE。

    posted @ 2012-04-15 18:53 paulwong 閱讀(4548) | 評(píng)論 (0)編輯 收藏

    工作流引擎Activiti使用總結(jié)

    http://www.kafeitu.me/activiti/2012/03/22/workflow-activiti-action.html


    源碼來(lái)了:
    https://github.com/henryyan/kft-activiti-demo

    posted @ 2012-04-09 16:39 paulwong 閱讀(2069) | 評(píng)論 (0)編輯 收藏

    調(diào)優(yōu)思路

    1、使用剖析器,如jvisualvm等工具抓快照,分析調(diào)用次數(shù)最多,和耗時(shí)最多的Java代碼;

    2、如果數(shù)據(jù)庫(kù)是Oracle,可以把數(shù)據(jù)庫(kù)遷移到11G進(jìn)行測(cè)試,11G里面也有一個(gè)剖析工具抓快照,可以分析出哪條SQL語(yǔ)句執(zhí)行最頻繁,哪條SQL執(zhí)行最耗時(shí);

    3、如果是WebApp,可以自己去修改clickstream的filter抓取和記錄所有的用戶請(qǐng)求,統(tǒng)計(jì)記錄結(jié)果中的訪問(wèn)次數(shù)和耗時(shí);

    posted @ 2012-04-09 00:37 paulwong 閱讀(255) | 評(píng)論 (0)編輯 收藏

    基于ZooKeeper的分布式Session實(shí)現(xiàn)

    http://my.oschina.net/jsan/blog/52151

    posted @ 2012-04-02 00:14 paulwong 閱讀(359) | 評(píng)論 (0)編輯 收藏

    ACTIVITI KICK START

    https://github.com/jbarrez/Activiti-KickStart

    一個(gè)基于ACTIVITI的內(nèi)容管理系統(tǒng):
    http://code.google.com/p/echoice/source/browse

    ACTIVITI中文使用手冊(cè):
    http://www.georgeinfo.com/file/activiti-doc.pdf

    posted @ 2012-04-01 00:43 paulwong 閱讀(286) | 評(píng)論 (0)編輯 收藏

    使用 WS-AtomicTransaction 和 JTA 的分布式事務(wù)

    http://wenku.baidu.com/view/f3126425ccbff121dd3683b3.html

    在現(xiàn)在的企業(yè)應(yīng)用程序的開(kāi)發(fā)中,Web 服務(wù)已經(jīng)越來(lái)越普遍。然而,從傳統(tǒng)意義上來(lái)說(shuō),它們還沒(méi)有達(dá)到和所支持的服務(wù)相同的水平。當(dāng)構(gòu)建 J2EE 應(yīng)用程序,特別是事務(wù)服務(wù)的時(shí)候,企業(yè)依賴于這些服務(wù)。本文概述了事務(wù)服務(wù)是如何在一個(gè)使用 Java Transaction API 的 J2EE 環(huán)境中的 Web 服務(wù)事務(wù)的幫助下,與 Web 服務(wù)實(shí)現(xiàn)無(wú)縫連接的。

    本文簡(jiǎn)要地概述了這項(xiàng)新的 Web 服務(wù)技術(shù)和已被證實(shí)的傳統(tǒng)的事務(wù)技術(shù),解釋了它們是如何能夠跨分布式的 J2EE 環(huán)境甚至跨不同的事務(wù)體系結(jié)構(gòu)來(lái)實(shí)現(xiàn)互操作的。

    本文假設(shè)您已經(jīng)對(duì)事務(wù)服務(wù)的概念(例如,ACID properties、提交/回滾、事務(wù)劃分,等等)的理解達(dá)到中級(jí)水平。要想了解事務(wù)服務(wù)的進(jìn)一步信息,特別是 JTS,請(qǐng)參考文章 Java theory and practice:Understanding JTS —— An introduction to transactions。這篇文章可以在 developerWorks 上找到(請(qǐng)參閱 參考資料)。同樣,我也想要推薦一本關(guān)于事務(wù)的更全面信息的好書(shū),它就是由 Philip Bernstein 和 Eric Newcomer 合著的 Principles of Transaction Processing(請(qǐng)參閱 參考資料


    什么是 Java Transaction API(JTA)?

    JTA 是事務(wù)服務(wù)的 J2EE 解決方案。本質(zhì)上,它是描述事務(wù)接口(比如 UserTransaction 接口,開(kāi)發(fā)人員直接使用該接口或者通過(guò) J2EE 容器使用該接口來(lái)確保業(yè)務(wù)邏輯能夠可靠地運(yùn)行)的 J2EE 模型的一部分。

    JTA 具有的三個(gè)主要的接口分別是 UserTransaction 接口、 TransactionManager 接口和 Transaction 接口。這些接口共享公共的事務(wù)操作,例如 commit()rollback() , 但是也包含特殊的事務(wù)操作,例如 suspend()resume()enlist() ,它們只出現(xiàn)在特定的接口上,以便在實(shí)現(xiàn)中允許一定程度的訪問(wèn)控制。例如, UserTransaction 能夠執(zhí)行事務(wù)劃分和基本的事務(wù)操作,而 TransactionManager 能夠執(zhí)行上下文管理。本文僅僅需要您對(duì) JTA 有一個(gè)基本的了解。


    JTA 的好處?

    JTA 是一個(gè)定義明確的事務(wù)服務(wù),向 J2EE 應(yīng)用程序開(kāi)發(fā)人員提供一種可以直接使用的服務(wù)。作為選擇,一個(gè)應(yīng)用程序也可能這樣部署,容器將代替開(kāi)發(fā)人員來(lái)管理事務(wù)行為。在后一種情況下,開(kāi)發(fā)人員能夠全神貫注于他們的應(yīng)用程序的業(yè)務(wù)邏輯,同時(shí)由 J2EE 容器來(lái)負(fù)責(zé)事務(wù)邏輯。

    模型明確的事務(wù)服務(wù)的好處是對(duì)于每個(gè)單獨(dú)的事務(wù)總是維持四個(gè) ACID 特性。盡管這是一個(gè)實(shí)現(xiàn)相關(guān)的問(wèn)題,WebSphere Application Server 提供為每個(gè)導(dǎo)入的或者導(dǎo)出的事務(wù)保護(hù)這些 ACID 特性的能力,而不管并發(fā)的事務(wù)數(shù)目是多少。


    JTA 的限制?

    經(jīng)歷過(guò)所有的事務(wù)體系結(jié)構(gòu),想要有效地將一組事務(wù)傳送給其他并不共享同樣模型的事務(wù)服務(wù),同時(shí)保持原子的工作單元,是非常困難的。在我們的案例中,建模的 JTA 運(yùn)行在 Java Transaction Service(JTS) 之上,JTS 處理輸入和輸出事務(wù)傳送的請(qǐng)求。

    因?yàn)?JTS 是一種由 CORBA 定義的對(duì)象事務(wù)服務(wù)(OTS)的 Java 實(shí)現(xiàn),它只能夠與另一個(gè) OTS 模型連接。因此, 一個(gè)事務(wù)只能傳送給另一個(gè) OTS-兼容的目標(biāo),典型地即另一個(gè) J2EE 實(shí)現(xiàn)。因?yàn)?JTA 和 JTS 規(guī)范沒(méi)有對(duì)這些接口的底層實(shí)現(xiàn)加以限制 (只要它們符合模型),事務(wù)可以安全地在兩個(gè) J2EE-兼容的應(yīng)用程序服務(wù)器之間傳送,而沒(méi)有丟失它們的 ACID 特性的風(fēng)險(xiǎn)。然而,J2EE 服務(wù)器并不必須處理非 J2EE 調(diào)用。

    某些 J2EE 服務(wù)器可能是例外;例如,WebSphere Application Server 將正確地處理一個(gè)與 CORBA 兼容事務(wù)相關(guān)聯(lián)的輸入的 CORBA 請(qǐng)求,將這個(gè)事務(wù)傳送給線程,然后在它的上下文里執(zhí)行事務(wù)工作。然而,在大多數(shù)情況下,當(dāng)您試圖在事務(wù)模型之間移動(dòng)的時(shí)候,您不得不超越 JTA 和 JTS,把目光投得更遠(yuǎn),在這里 Web 服務(wù)出現(xiàn)了。


    什么是 Web 服務(wù)?

    Web 服務(wù)是一種能夠作為應(yīng)用程序一部分部署在可訪問(wèn)的服務(wù)器上供內(nèi)部和外部客戶使用的對(duì)象。Web 服務(wù)由它的 Web 服務(wù)描述語(yǔ)言(WSDL)來(lái)描述。它定義了一個(gè)使用基于 XML 調(diào)用(典型地使用 SOAP 協(xié)議)的 Web 服務(wù)的輸入和輸出參數(shù)的用法。例如,客戶端可以查看已經(jīng)由服務(wù)器發(fā)布的 WSDL,然后構(gòu)造客戶端代碼來(lái)調(diào)用 Web 服務(wù)。一旦完成,它就能夠通過(guò)將 SOAP 消息傳遞給 Web 服務(wù)的一個(gè)方法來(lái)調(diào)用它。在這條 SOAP 消息中包括諸如方法 名稱的信息以及任何它所需要的參數(shù)。返回值將在另一條 SOAP 消息里被傳送回來(lái),再由客戶提取出來(lái)。


    使用 Web 服務(wù)的好處?

    Web 服務(wù)由哪種語(yǔ)言編寫(xiě)而成并不重要,因?yàn)?WSDL 沒(méi)有定義語(yǔ)言或者編程的模型相關(guān)的細(xì)節(jié)(例如,Java 和 J2EE 技術(shù))。這就給了 Web 服務(wù)的作者和客戶端的作者選擇他首選的解決方案 的靈活性。

    讓我們來(lái)比較一下 Web 服務(wù)和 Enterprise JavaBean(EJB)組件。EJB 組件要求 RMI-編譯的代碼,以便使客戶端能夠訪問(wèn),所以 它能夠像它的代理一樣創(chuàng)造本地的存根(stub)對(duì)象。因此,這將需要在每一次它們改變的時(shí)候,向所有的客戶端重新分配存根(stub)。 無(wú)論如何,和 Web 服務(wù)一起您將使用 WSDL,所以客戶端能夠構(gòu)造它們自己的客戶端調(diào)用代碼,在本地類路徑上不需要服務(wù)器的類來(lái)執(zhí)行調(diào)用。這個(gè)模型提供了一個(gè)非常巧妙的方法調(diào)用過(guò)程。 EJB,作為 J2EE 模型的一部分,必須使用 Java 客戶來(lái)調(diào)用,最好是一個(gè) J2EE 管理的客戶端。另一方面,Web 服務(wù)可以被任何客戶端代碼所調(diào)用,這個(gè)代碼能夠構(gòu)造一個(gè)結(jié)構(gòu)良好的 SOAP 請(qǐng)求。因而,舉例來(lái)說(shuō),一個(gè)部署在 J2EE 服務(wù) 器上的 Web 服務(wù)能夠使用 C++ 客戶來(lái)調(diào)用。


    Web 服務(wù)的限制?

    因?yàn)?Web 服務(wù)請(qǐng)求(通過(guò) HTTP 的 SOAP)的性質(zhì)與其他的方法調(diào)用(例如,一個(gè)使用通過(guò) IIOP 的 RMI 的 EJB 調(diào)用)差別很大,支持執(zhí)行分布式事務(wù)的代碼直到最近才可獲得。這已經(jīng)成為在 使用 Web 服務(wù)作為分布式事務(wù)企業(yè)應(yīng)用程序一部分時(shí),主要的問(wèn)題。本質(zhì)上,Web 服務(wù)不能運(yùn)行在 Web 服務(wù)調(diào)用之前開(kāi)始的事務(wù)上下文 中,也不能將一個(gè)事務(wù)上下文傳送給另一個(gè)組件。


    那么,問(wèn)題是什么呢?

    如果 Web 服務(wù)被用于工業(yè),必須確保它們?cè)谑聞?wù)環(huán)境 中運(yùn)行的時(shí)候,以可靠的和可預(yù)知的方式工作。直到現(xiàn)在,Web 服務(wù)只能夠使用獨(dú)立于其他組件的事務(wù)——在 Web 服務(wù)的方法范圍里劃分的 和服從它的底層的事務(wù)實(shí)現(xiàn)的規(guī)則——并且物理上不能離開(kāi) Web 服務(wù)或者進(jìn)入另一個(gè) Web 服務(wù)。企業(yè)應(yīng)用程序具有始終在企業(yè)組件間流動(dòng) 的事務(wù)。這需要成為 Web 服務(wù)的標(biāo)準(zhǔn)來(lái)確保它們能夠被正確地使用,通過(guò)利用 Web 服務(wù)的功能僅僅忽略在我們的所有嚴(yán)格的企業(yè)應(yīng)用 程序中依賴的和使用的事務(wù)支持來(lái)避免改變您的編程風(fēng)格。


    那么,解決方案是什么呢?

    解決方案就是一種稱為 Web 服務(wù)事務(wù)(WS-Transaction) 的新技術(shù)。它能夠調(diào)整事務(wù)的上下文。這個(gè)上下文可以被 Web 服務(wù)、其他的諸如 EJB 的 J2EE 組件、甚至其他支持 WS-Transaction 的 非 J2EE 事務(wù)服務(wù)使用。

    WS-Transaction 是一個(gè)規(guī)范。它擴(kuò)展了 Web 服務(wù)協(xié)調(diào)(WS-Coordination)規(guī)范來(lái)定義一種支持原子事務(wù)的協(xié)調(diào)。


    什么是 WS-Coordination

    WS-Coordination 是一個(gè)協(xié)調(diào)框架來(lái)使分布的參與者 能夠在他們個(gè)體行動(dòng)之上就一個(gè)通用的結(jié)果達(dá)成協(xié)議。

    本質(zhì)上,這意味著分布式的參與者(例如,在不同機(jī)器上的兩個(gè)應(yīng)用程序服務(wù)器)將能夠使用 WS-Coordination 把每個(gè)參與者 的行為集在合一起,進(jìn)一步地,并且通過(guò)確保它們完全同意對(duì)于在這個(gè)協(xié)調(diào)上下文里它們各自執(zhí)行的所有行為均產(chǎn)生單一的結(jié)果,來(lái) 進(jìn)一步管理這些行為。否則,則不能以一個(gè)受控的方式來(lái)完成這些功能。

    協(xié)調(diào)上下文可以被看作是一個(gè)標(biāo)識(shí)符,行為執(zhí)行在這個(gè)標(biāo)識(shí)符之下。作一比較,這個(gè)概念非常類似于事務(wù)上下文。當(dāng)事務(wù)工作完成, 在事務(wù)上下文里管理它,當(dāng)調(diào)用這個(gè)上下文去確定或會(huì)滾時(shí)這個(gè)工作完成。協(xié)調(diào)上下文包含的附加信息是一個(gè)協(xié)調(diào)標(biāo)識(shí)符、關(guān)于協(xié)調(diào)類型的 詳細(xì)資料以及包括端口信息以便協(xié)調(diào)服務(wù)能夠被訪問(wèn)的協(xié)調(diào)協(xié)議。在下面定義了這些術(shù)語(yǔ)。

     

    協(xié)調(diào)服務(wù),或者 協(xié)調(diào)器(Coordinator), 進(jìn)一步由三個(gè)服務(wù)組成: 激活服務(wù)(activation service)注冊(cè)服務(wù)(registration service)協(xié)調(diào)協(xié)議(coordination protocol) 服務(wù)。激活服務(wù)支持 CreateCoodinationContext 操作來(lái)允許新的協(xié)調(diào)上下文存在。注冊(cè)服務(wù)支持 Register 操作來(lái)允許參與者 在協(xié)調(diào)上下文中執(zhí)行工作。協(xié)調(diào)協(xié)議服務(wù)支持協(xié)調(diào)協(xié)議的使用,這個(gè)協(xié)議定義了協(xié)調(diào)器(Coordinator)和參與者之間的行為和通信。

    協(xié)調(diào)類型是一個(gè)協(xié)調(diào)行為的固定的集合,這個(gè)集合詳細(xì)說(shuō)明了協(xié)調(diào)協(xié)議的集合以及協(xié)調(diào)器(Coordinator)應(yīng)該如何驅(qū)動(dòng)完成。 WS-Transaction 規(guī)范描述了兩個(gè)協(xié)調(diào)類型—— 原子事務(wù)(Atomic Transaction)(AT)和 業(yè)務(wù)協(xié)定(Business Agreement)(BA)。 這些協(xié)調(diào)類型中的每一個(gè)都包括協(xié)調(diào)協(xié)議。例如,原子事務(wù)(Atomic Transaction)協(xié)調(diào)類型包括像 two-phase commit protocol(Durable2PC)和 phaseZero protocol(Volatile2PC)這樣的協(xié)調(diào)協(xié)議。 您可以希望在支持原子事務(wù)的環(huán)境中使用這兩個(gè)協(xié)議。

    業(yè)務(wù)協(xié)定(Business Agreement)協(xié)調(diào)類型提供了一種不同的功能類型。它被設(shè)計(jì)成用于更長(zhǎng)的時(shí)幀。而不像原子事務(wù),正常地您 與它聯(lián)系一個(gè)非常短的生命期。業(yè)務(wù)協(xié)定協(xié)議(Business Agreement protocol)的一個(gè)例子就是它自己,被稱作業(yè)務(wù)協(xié)定(Business Agreement) 它是一個(gè)補(bǔ)償協(xié)議。


    WS-Coordination 和 WS-Transaction 之間是什么關(guān)系?

    WS-Coordination 是基本的框架,使參與者之間活動(dòng)的分布式結(jié)果成為可能。WS-Transaction 定義了協(xié)調(diào)類型,例如原子事務(wù)(Atomic Transaction),協(xié)調(diào)類型使用 WS-Coordination 框架來(lái)定義規(guī)則。在協(xié)調(diào)器(Coordinator)和參與者通信時(shí),它們必須遵循這些規(guī)則。兩者之間的這個(gè)區(qū)別很重要。

    兩個(gè)應(yīng)用程序和一個(gè)協(xié)調(diào)器(Coordinator)之間主要的協(xié)調(diào)流程如下面的 圖 1所示。


    圖 1. 基本協(xié)調(diào)流程
    1. App1 向在協(xié)調(diào)器上的激活服務(wù)提出一個(gè)請(qǐng)求。
    2. 協(xié)調(diào)器開(kāi)始一個(gè)新的活動(dòng),使用它的 CoordinationContext (協(xié)調(diào)器的 XML 消息)來(lái)對(duì) App1 做出響應(yīng)。
    3. App1向注冊(cè)服務(wù)提出請(qǐng)求來(lái)注冊(cè)使用協(xié)調(diào)協(xié)議X。
    4. App1 以它期望的方式調(diào)用 App2,傳遞 CoordinationContext 給協(xié)調(diào)器。
    5. App2 向注冊(cè)服務(wù)提出請(qǐng)求(使用諸如端口信息的參數(shù),它們 可以在 App1 傳遞的 CoordinationContext 中找到)來(lái)注冊(cè)使用協(xié)調(diào)協(xié)議Y。
    6. App2結(jié)束它的工作,將控制返還給 App1,活動(dòng)結(jié)束。
    7. 協(xié)調(diào)器使用協(xié)議 X 類型消息響應(yīng) App1
    8. 協(xié)調(diào)器使用協(xié)議 Y 類型消息響應(yīng) App2


    協(xié)調(diào)器調(diào)解

    在一個(gè)現(xiàn)實(shí)世界的情況中,Web 服務(wù)可能是事務(wù)的和分布式的,協(xié)調(diào)器的發(fā)起者( App1)將 CoordinationContext 傳遞給任何它所期望的活動(dòng)中的參與者( App2)。這個(gè)上下文的接收者有兩種選擇:它們可以使用已經(jīng)創(chuàng)建好了的協(xié)調(diào)器( Ca),或者如果它們?cè)敢猓部梢栽诔跏嫉?CoordinationContext 中傳遞創(chuàng)建的新的協(xié)調(diào)器。然后,第二種選擇將新的協(xié)調(diào)器( Cb) 作為 App2的代理協(xié)調(diào)器。它將包括與協(xié)調(diào)器 Ca相同的活動(dòng)標(biāo)識(shí)符,但是當(dāng) App2向它的協(xié)調(diào)器 Cb注冊(cè) Durable2PC 協(xié)議的時(shí)候,它的請(qǐng)求直接傳送給了協(xié)調(diào)器 Ca。 類似地,在結(jié)束時(shí),準(zhǔn)備和提交消息在最終到達(dá) App2(它已經(jīng)注冊(cè)過(guò) Durable2PC 協(xié)議)之前將從協(xié)調(diào)器 Ca傳遞給協(xié)調(diào)器 Cb

    請(qǐng)參閱 WS-Transaction 規(guī)范的 4.1 節(jié) AT3.1 Example Atomic Transaction Message Flow,在那里您將看到一個(gè)應(yīng)用程序和調(diào)解的協(xié)調(diào)器之間的 WS-Coordination 流程的非常好的示例(請(qǐng)參閱 參考資料)。


    Web 服務(wù)事務(wù):原子事務(wù)(WS-AtomicTransaction)

    WS-AtomicTransaction 是一種對(duì)于原子事務(wù)的特殊的協(xié)調(diào)類型,它提供了一組協(xié)調(diào)協(xié)議。這些協(xié)調(diào)協(xié)議是:

    • Completion
    • CompletionWithAck
    • Volatile2PC
    • Durable2PC
    • OutcomeNotification

    當(dāng)協(xié)調(diào)上下文創(chuàng)建以后,協(xié)調(diào)類型被指定,但是協(xié)調(diào)協(xié)議直到注冊(cè)時(shí)才被指定。任何參與者可以注冊(cè)任意數(shù)目的協(xié)調(diào)協(xié)議,應(yīng)該發(fā)送和接收 由協(xié)議定義的恰當(dāng)?shù)南ⅰ@纾绻粋€(gè)參與者在協(xié)調(diào)器中注冊(cè)了 Durable2PC 協(xié)議,當(dāng)完成時(shí)一條準(zhǔn)備消息將被發(fā)送給這個(gè)參與者,它們將被認(rèn)為以與正常的事務(wù)資源相似的方式投票。想要了解這里每個(gè)協(xié)議的信息和它們的狀態(tài)圖,請(qǐng)查閱 WS-Transaction 規(guī)范, 第 4 節(jié) AT3 Coordination protocols(請(qǐng)參閱 參考資料)。


    如何能將 JTA 事務(wù)和 WS-AtomicTransaction 一起使用?

    因?yàn)?JTA 和 JTS 是實(shí)現(xiàn)相關(guān)的,我將使用的這個(gè)示例是 WebSphere Application Server V5.0.2 和 WS-Transaction Tech Preview。這個(gè)場(chǎng)景將有兩臺(tái)機(jī)器,每個(gè)上都運(yùn)行有應(yīng)用程序服務(wù)器,如 圖 2 所示。 應(yīng)用程序服務(wù)器A部署并運(yùn)行一個(gè) Bean Managed Transaction(BMT)EJB 組件。應(yīng)用程序服務(wù)器B部署并運(yùn)行一個(gè) Web 服務(wù)。 EJB 組件通過(guò)使用 JTA 提供的接口 UserTransaction 開(kāi)始一個(gè)事務(wù)。它對(duì) XA-compliant database 執(zhí)行事務(wù)工作(步驟 1),然后使用 SOAP/HTTP 向在應(yīng)用程序服務(wù)器B上的 Web 服務(wù)發(fā)送一個(gè)請(qǐng)求(步驟 2)。Web 服務(wù)對(duì) XA-compliant database 執(zhí)行工作(步驟 3),然后返回到 EJB 組件(步驟 4),由它再次使用 UserTransaction 接口來(lái)提交事務(wù)。所有由 EJB 和 Web 服務(wù)對(duì)數(shù)據(jù)庫(kù)執(zhí)行的事務(wù)都已經(jīng)被包含在一個(gè)活動(dòng)的范圍里,這個(gè)活動(dòng)是由協(xié)調(diào)器恰好在調(diào)用 Web 服務(wù)(步驟 2)之前創(chuàng)建的,它已經(jīng)被提交,同時(shí)保存著所有的 ACID 特性,它就好像是單一的工作單元。

    讓我們來(lái)看看下面的兩個(gè)領(lǐng)域——J2EE 領(lǐng)域和 Web 服務(wù)領(lǐng)域。在 J2EE 領(lǐng)域里,使用的事務(wù)模型是 JTA。在 Web 服務(wù)領(lǐng)域里, 使用的事務(wù)模型是 WS-AtomicTransaction。WebSphere Application Server 把一個(gè) Java Web 服務(wù)看作是一個(gè) J2EE 對(duì)象,因此也就 意味著,Web 服務(wù)的實(shí)現(xiàn)屬于 J2EE 領(lǐng)域,而調(diào)用屬于 Web 服務(wù)領(lǐng)域。在 WebSphere 領(lǐng)域,正確地驅(qū)動(dòng)協(xié)議總是正在被使用的模型 (JTA 或者 WS-AtomicTransaction)的責(zé)任。

    圖 2 展示了 在一個(gè)事務(wù)企業(yè)應(yīng)用程序中包含 Web 服務(wù)是多么的容易,同時(shí)也展示了對(duì)于沒(méi)有費(fèi)一行代碼麻煩就在導(dǎo)入的事務(wù)上下文中運(yùn)行這個(gè) Web 服務(wù)的用戶來(lái)說(shuō),它又是多么的無(wú)縫。


    圖 2. 使用 JTA 事務(wù)和 WS-AtomicTransaction 事務(wù)

    請(qǐng)注意:The EJB 組件正運(yùn)行在一個(gè)受管理的環(huán)境中(EJB 容器)并且 Web 服務(wù)是符合 JSR 109。

    它只能和 JTA 一起工作嗎?

    WS-Coordination 依靠它的基于XML的調(diào)用來(lái) 利用它本身是 Web 服務(wù)的優(yōu)勢(shì)。因?yàn)橛脕?lái)調(diào)用 WS-Coordination 操作的協(xié)議是 SOAP,消息內(nèi)容是 XML 格式的純文本。這意味著,當(dāng)使用 HTTP 傳遞給 Web 服務(wù)時(shí),將不能僅僅通過(guò) SOAP 包本身來(lái)確定客戶的詳細(xì)資料,例如編程語(yǔ)言。因此,WS-AtomicTransaction 將能夠與任何其他的使用任何支持 WS-AtomicTransaction 的編程語(yǔ)言編碼的事務(wù)服務(wù)相連接。

    在近來(lái)的一個(gè)由 IBM 和 Microsoft 主辦的 Web 服務(wù)演示上,展示了 WS-AtomicTransaction 的這個(gè)跨事務(wù)服務(wù)和編程語(yǔ)言的互操作性。 圖 3 展示了一個(gè)示范這項(xiàng)技術(shù)的場(chǎng)景。

    圖 3 中有一個(gè).NET 服務(wù)器開(kāi)始一個(gè)非 JTA 事務(wù),向兩個(gè) WebSphere 應(yīng)用程序服務(wù)器和另外一個(gè).NET 服務(wù)器提出了 Web 服務(wù)調(diào)用請(qǐng)求。每個(gè)應(yīng)用程序服務(wù)器都使用它們的底層事務(wù)服務(wù)來(lái)執(zhí)行事務(wù)工作。每次您能夠使用 WS-Transaction 調(diào)用一個(gè)您將轉(zhuǎn)到的 Web 服務(wù)。當(dāng)發(fā)起者完成事務(wù),您使用 WS-Transaction 技術(shù)來(lái)協(xié)調(diào)每個(gè)參與者,確保它們都已完成,就好像它們是單一的工作單元似的。


    圖 3. 在 Steve Mills 和 Bill Gates 的 Web 服務(wù)演示中的一個(gè) WS-AtomicTransaction 場(chǎng)景的示例拓?fù)洹? src=

    總結(jié)

    在本文中,您已經(jīng)了解到 WS-Coordination 和 WS-Transaction 的基本概念。到現(xiàn)在為止,Web 服務(wù)還不能在分布式環(huán)境里使用事務(wù)。WS-Transaction 允許 Web 服務(wù)執(zhí)行事務(wù)工作,這個(gè)事務(wù)工作作為更廣泛的活動(dòng)生成組件、應(yīng)用程序服務(wù)器、甚至實(shí)現(xiàn)的一部分,正如在 IBM 和 Microsoft Web 服務(wù)演示中所展示的。

    在 WS-Transaction 的支持下,我們能夠可靠地使用 Web 服務(wù)作為我們的企業(yè)應(yīng)用程序的一部分,因?yàn)樗呀?jīng)為事務(wù)支持嵌入到其他的企業(yè)組件里。

    posted @ 2012-03-30 00:21 paulwong 閱讀(936) | 評(píng)論 (0)編輯 收藏

    分布式事務(wù)

    一、 事務(wù)概述

    1、 事務(wù)協(xié)議

    WCF相關(guān)的事務(wù)協(xié)議有三個(gè)。

    1.1. Lightweight protocol

    這是個(gè)輕量級(jí)的本地事務(wù)協(xié)議,限制管理在一個(gè)AppDomain中的事務(wù)。不能跨AppDomain邊界傳播事務(wù),也不能跨服務(wù)邊界傳播事務(wù)。跟其他協(xié)議比,Lightweight protocol是最有效率的協(xié)議。

    1.2. OleTx protocol

    這個(gè)協(xié)議可用于跨AppDomain,進(jìn)程和機(jī)器邊界,管理兩階段提交的事務(wù)協(xié)議。這個(gè)跨邊界的事務(wù)協(xié)議使用RPC,是二進(jìn)制的,windows專有的協(xié)議,不能穿越防火墻,也不能用于與非windows系統(tǒng)的互操作。在windows環(huán)境下的局域網(wǎng),OleTx協(xié)議是很好的分布式事務(wù)的管理協(xié)議。

    1.3. WS-Atomic Transaction (WSAT) protocol

    WSATOleTx協(xié)議類似,也可以跨AppDomain,進(jìn)程和機(jī)器邊界,管理兩階段提交的事務(wù)協(xié)議。但WSAT不是微軟的專有協(xié)議,此協(xié)議是微軟、IBMBEA等公司共同提出的工業(yè)標(biāo)準(zhǔn)。此協(xié)議也可用于Intranet中,但是更多的是用于在Internet環(huán)境下,或者跟非windows系統(tǒng)進(jìn)行互操作的分布式事務(wù)。

    說(shuō)到WSAT協(xié)議這里有必要一下分布式事務(wù)的發(fā)展。

    分布式事務(wù):

    分布式事務(wù)在企業(yè)應(yīng)用中是很重要的一個(gè)方面,微軟使用MSDTC作為分布式事務(wù)管理器,使用OleTx事務(wù)協(xié)議進(jìn)行分布式事務(wù)管理,但是OleTx事務(wù)協(xié)議是微軟的專有協(xié)議,不是公認(rèn)標(biāo)準(zhǔn)。在分布式環(huán)境中異構(gòu)系統(tǒng)的交互一定要有個(gè)公認(rèn)同意的分布式事務(wù)標(biāo)準(zhǔn)才能在異構(gòu)的系統(tǒng)中實(shí)現(xiàn)分布式事務(wù)的協(xié)調(diào)。

    l OGMXA事務(wù)規(guī)范

    1994年,開(kāi)放組織(Open Group)的 X/Open 分布式事務(wù)流程(DTP)模型,它定義了 應(yīng)用程序如何使用 事務(wù)管理程序跨多個(gè) 資源管理程序來(lái)協(xié)調(diào)分布式事務(wù)。如果事務(wù)是通過(guò)遵循 XA 的事務(wù)管理程序來(lái)進(jìn)行協(xié)調(diào)的,則任何遵循 XA 規(guī)范的資源管理程序都可以參與該事務(wù),因此就可以讓不同廠商的事務(wù)產(chǎn)品可以共同工作。所有遵循 XA 的事務(wù)都是分布式事務(wù)。XA 既支持一步提交,也支持兩階段提交。

    對(duì)象管理組(Object Management Group)的通用對(duì)象請(qǐng)求代理體系結(jié)構(gòu)對(duì)象事務(wù)服務(wù)(Common Object Request Broker Architecture Object Transaction Service -- 定義遵循規(guī)范的流程如何跨多個(gè)流程線程將事務(wù)上下文從一個(gè)流程傳播到另一個(gè)流程。這種傳播使得即使分布式對(duì)象運(yùn)行于來(lái)自不同廠商的容器中,也可以在單個(gè)事務(wù)中合作。CORBA OTS 規(guī)范建立在 XA 規(guī)范的基礎(chǔ)之上。

    l OASISBusiness Transaction ProtocolBTP)標(biāo)準(zhǔn)

    2001 年, 一個(gè)由各大公司(包括惠普公司(Hewlett-PackardHP)、甲骨文公司(Oracle)及BEA公司)組成的聯(lián)盟開(kāi)始著手創(chuàng)建 Organization for Advance Structured Information Systems (OASIS) Business Transaction ProtocolBTP)標(biāo)準(zhǔn)。

    BTP 不是專門(mén)用于 Web 服務(wù)的事務(wù)處理協(xié)議,它的目的是它也能用于其他的環(huán)境中。因而,BTP 定義了事務(wù)性的 XML 協(xié)議,并且必須在規(guī)范中指定所有的服務(wù)依賴性。

    BTP協(xié)議相對(duì)比較復(fù)雜,并且它把原子性事務(wù)和長(zhǎng)時(shí)間運(yùn)行的商業(yè)事務(wù)放在一起進(jìn)行管理,這樣它必須解決各種各樣不同的問(wèn)題。它是通過(guò)放松限制來(lái)這樣做的,這表面上給人感覺(jué)靈活度很高,但是很多東西就留給實(shí)現(xiàn)者去實(shí)現(xiàn)了,導(dǎo)致使用比較復(fù)雜。

    l OASISWS-Transactions

    BTP出現(xiàn)后,其他一些行業(yè)大公司,包括 IBMMicrosoft BEA,又發(fā)布了它們自己的規(guī)范: Web 服務(wù)事務(wù)處理(WS-Transactions),由三部分組成WS-Coordination(事務(wù)協(xié)調(diào)器)、WS-AtomicTransaction(實(shí)現(xiàn)原子事務(wù))、WS-BusinessActivity(實(shí)現(xiàn)長(zhǎng)時(shí)間運(yùn)行的商業(yè)事務(wù))。WS-TransactionsBTP好的方面是它將事務(wù)協(xié)調(diào)器獨(dú)立出來(lái),另外用兩個(gè)標(biāo)準(zhǔn)在WS-Transactions基礎(chǔ)上分別實(shí)現(xiàn)原子事務(wù)和長(zhǎng)時(shí)間運(yùn)行的事務(wù),這樣簡(jiǎn)化了復(fù)雜性。

    WS-Transactions是專門(mén)用于web services的事務(wù)規(guī)范。

    2005年,WS-Transactions發(fā)布了第一個(gè)版本,Version 1.0

    2007年,WS-Transactions發(fā)布了Version 1.1,并被OASIS組織接受為標(biāo)準(zhǔn),成為WS-*標(biāo)準(zhǔn)的一部分。

    WCF支持的可互操作的分布式事務(wù)協(xié)議只有WS-Transactions,并且只實(shí)現(xiàn)了WS-CoordinationWS-AtomicTransactionWS-BusinessActivity沒(méi)被實(shí)現(xiàn)。

    1.3.1. WS-Coordination

    WS-Coordination它描述了一個(gè)可擴(kuò)展的交流協(xié)議框架,該框架對(duì)分布式的請(qǐng)求進(jìn)行其請(qǐng)求協(xié)議的判斷與處理,處理后再將請(qǐng)求向下方的業(yè)務(wù)處理模塊進(jìn)行分發(fā)。

    該 框架最大特點(diǎn)是其能夠以系統(tǒng)流程代理的身份來(lái)處理請(qǐng)求。當(dāng)不同的請(qǐng)求,無(wú)論是內(nèi)部的同系統(tǒng)的請(qǐng)求或外部的異構(gòu)系統(tǒng)的請(qǐng)求,經(jīng)過(guò)該框架處理后,再其原有的特 殊的傳輸代理層上添加了符合本系統(tǒng)信息流規(guī)則的本地協(xié)議。也就是本系統(tǒng)允許已經(jīng)存在的事務(wù)、工作流或其他服務(wù)的請(qǐng)求隱藏其自身獨(dú)特的傳輸協(xié)議,并可順利運(yùn) 行于異構(gòu)式的系統(tǒng)環(huán)境中。

    當(dāng)前WS-Coordination穩(wěn)定的版本是1.1,同樣是OASIS2007年發(fā)布的國(guó)際標(biāo)準(zhǔn)。現(xiàn)在1.2版本也在起草過(guò)程之中。WS-Coordination規(guī)范的具體實(shí)現(xiàn)需要開(kāi)發(fā)中在基于XML的配置文件中引入WS-Coordination規(guī)范的命名空間,如指定<xsschema>字段的值為ws-addr.xsd。由于是基于XML文件來(lái)實(shí)現(xiàn),WS-Coordination規(guī)范易于實(shí)現(xiàn),且對(duì)日后的擴(kuò)展支持度高。

    通過(guò)WS-Coordination的使用,一方面通過(guò)附加統(tǒng)一的本地協(xié)議,在使用不同通信協(xié)議的請(qǐng)求到來(lái)時(shí),進(jìn)行統(tǒng)一的協(xié)議處理,加快了請(qǐng)求的處理速度,提高了系統(tǒng)的松耦合性;另一方面WS-Coordination規(guī)范所定義的框架加強(qiáng)了系統(tǒng)的異構(gòu)性,使系統(tǒng)不因請(qǐng)求所使用的協(xié)議不同而無(wú)法處理,這提升了系統(tǒng)整體的兼容性,加強(qiáng)了系統(tǒng)的綜合服務(wù)能力。

    1.3.2. WS-AtomicTransaction

    WS-AtomicTransaction 定義了一組特定的協(xié)議,這組協(xié)議可以插入 WS-Coordination 模型,以實(shí)現(xiàn)傳統(tǒng)的兩階段原子事務(wù)處理協(xié)議。注意到原子的兩階段模型只是就涉及的服務(wù)而言的非常重要。提供服務(wù)的站點(diǎn)或基礎(chǔ)體系結(jié)構(gòu)可能大肆宣傳兩階段提交,但是卻使用一些其他的企業(yè)內(nèi)部模型,比如補(bǔ)償模型或版本模型。這種自由使簡(jiǎn)單的兩階段提交模型對(duì)于長(zhǎng)期運(yùn)行的 Internet 計(jì)算更有用。

    WCF實(shí)現(xiàn)了WS-AtomicTransaction協(xié)議,事務(wù)管理器是由MSDTC實(shí)現(xiàn),也就是說(shuō)在WCF中可以使用WS-AtomicTransaction協(xié)議進(jìn)行分布式事務(wù)的管理,并跟其他實(shí)現(xiàn)了WS-AtomicTransaction的異構(gòu)分布式事務(wù)互操作。

    1.3.3. WS-BusinessActivity

    WS-BusinessActivity 定義了一組特定的協(xié)議,這組協(xié)議可以插入 WS-Coordination 模型,以實(shí)現(xiàn)長(zhǎng)期運(yùn)行的、基于補(bǔ)償?shù)氖聞?wù)處理協(xié)議。

    WS-BusinessActivity定義的是long-running事務(wù),所謂long-running事務(wù)是指那些企業(yè)業(yè)務(wù)流程,需要跨應(yīng)用、跨企業(yè)來(lái)完成某個(gè)事務(wù),甚至在事務(wù)流程中還需要有手工操作的參與,這類事務(wù)的完成時(shí)間可能以分計(jì),以小時(shí)計(jì),甚至可能以天計(jì),這類事務(wù)也被稱為SAGA

    這類事務(wù)如果按照事務(wù)的ACID的要求去設(shè)計(jì),勢(shì)必造成系統(tǒng)的可用性大大的降低。試想一個(gè)由兩臺(tái)服務(wù)器一起參與的事務(wù),服務(wù)器A發(fā)起事務(wù),服務(wù)器B參與事務(wù),B的事務(wù)需要人工參與,所以處理時(shí)間可能很長(zhǎng)。如果按照ACID的原則,要保持事務(wù)的隔離性、一致性,服務(wù)器A中發(fā)起的事務(wù)中使用到的事務(wù)資源將會(huì)被鎖定,不允許其他應(yīng)用訪問(wèn)到事務(wù)過(guò)程中的中間結(jié)果,直到整個(gè)事務(wù)被提交或者回滾。這就造成事務(wù)A中的資源被長(zhǎng)時(shí)間鎖定,系統(tǒng)的可用性將不可接受。

    WS-BusinessActivity提供了一種基于補(bǔ)償?shù)?/span>long-running的事務(wù)處理模型。還是上面的例子,服務(wù)器A的事務(wù)如果執(zhí)行順利,那么事務(wù)A就先行提交,如果事務(wù)B也執(zhí)行順利,則事務(wù)B也提交,整個(gè)事務(wù)就算完成。但是如果事務(wù)B執(zhí)行失敗,事務(wù)B本身回滾,這時(shí)事務(wù)A已經(jīng)被提交,所以需要執(zhí)行一個(gè)補(bǔ)償操作,將已經(jīng)提交的事務(wù)A執(zhí)行的操作作反操作,恢復(fù)到未執(zhí)行前事務(wù)A的狀態(tài)。這樣的SAGA事務(wù)模型,是犧牲了一定的隔離性和一致性的,但是提高了long-running事務(wù)的可用性。

    目前的WCF中未實(shí)現(xiàn)WS-BusinessActivity,在WCF 4.0 beta2中也為實(shí)現(xiàn),估計(jì)在WCF 4.0正式版中也不會(huì)實(shí)現(xiàn)WS-BusinessActivity協(xié)議。

    2、 事務(wù)管理器

    管理事務(wù)必須有相應(yīng)的協(xié)議外,還必須有個(gè)事務(wù)管理器,事務(wù)管理器通過(guò)相應(yīng)的事務(wù)協(xié)議對(duì)本機(jī)的事務(wù)進(jìn)行管理。如果同一個(gè)事務(wù)需要跨機(jī)器,則每臺(tái)參與事務(wù)的機(jī)器的事務(wù)管理器之間進(jìn)行相互協(xié)調(diào)共同完成一個(gè)分布式事務(wù)。

    2.1. LTM

    輕型事務(wù)管理器Lightweight Transaction Manager,只能管理本地事務(wù),事務(wù)在一個(gè)AppDomain內(nèi)。LTM使用Lightweight protocol管理兩階段提交的事務(wù)。LTM只能管理單一的可持久化的資源,如果有兩個(gè)以上的可持久化資源登記到事務(wù)中,LTM將被升級(jí)到DTC管理器。

    2.2. KTM

    Vistawindows2008引入了內(nèi)核事務(wù)管理器Kernel Transaction Manager (KTM)

    Windows Vista中還引入了兩個(gè)主要的事務(wù)資源,事務(wù)NTFS和事務(wù)注冊(cè)表,稱作核心資源kernel resource managers (KRM)KTM可以管理這兩類資源。

    事務(wù)性 NTFS,也稱為 TxF,使用TxF可以將文件操作納入到事務(wù)管理中,在事務(wù)中的的文件操作將同事務(wù)中的其他事務(wù)資源一樣在事務(wù)前后保持一致性。

    同樣事務(wù)性注冊(cè)表,也稱作TxR,注冊(cè)表的操作也可以納入到事務(wù)管理中。

    KTMLTM一樣,使用Lightweight protocol管理兩階段提交的事務(wù),只能管理本地事務(wù),事務(wù)在一個(gè)AppDomain內(nèi),只能管理單一的可持久化的資源。

    2.3. DTC

    DTC可以管理任何跨越執(zhí)行邊界的事務(wù),跨AppDomain,跨進(jìn)程,跨機(jī)器,跨服務(wù)。DTC可以使用OleTx 或者WSAT事務(wù)協(xié)議。

    DTC既可以管理本地事務(wù),更重要的是它能夠管理跨邊界的服務(wù)。

    在使用WCF的場(chǎng)景下,每臺(tái)運(yùn)行WCF服務(wù)的機(jī)器都默認(rèn)使用DTCDTC建立一個(gè)新事務(wù),并跨機(jī)器把事務(wù)傳播到其他機(jī)器,發(fā)起事務(wù)的機(jī)器上的事務(wù)為根事務(wù),這個(gè)機(jī)器上的DTC就要負(fù)責(zé)這個(gè)分布式事務(wù)的協(xié)調(diào)任務(wù),負(fù)責(zé)啟動(dòng)事務(wù),提交事務(wù),和回滾事務(wù)。

    事務(wù)管理器可使用的事務(wù)協(xié)議:

    Protocal

    LTM

    KTM

    DTC

    Lightweight protocol

    Yes

    Yes

    No

    OleTx protocol

    No

    No

    Yes

    WS-Atomic Transaction

    No

    No

    Yes

    3、 事務(wù)資源

    在事務(wù)范圍內(nèi),可納入事務(wù)管理的資源,即可以在事務(wù)正常執(zhí)行后提交生效,在事務(wù)失敗可以回滾恢復(fù)到事務(wù)啟動(dòng)前狀態(tài)的資源成為事務(wù)資源。最常見(jiàn)的事務(wù)資源就是常用的數(shù)據(jù)庫(kù)操作。但是在vista開(kāi)始引入了兩個(gè)核心事務(wù)資源:TxF事務(wù)文件和TxR事務(wù)注冊(cè)表。

    可用的事務(wù)資源:

    3.1. sql server事務(wù)資源

    Sql 2005sql 2008的事務(wù)資源是新sql serverLTM事務(wù)管理器可以管理這類事務(wù)。

    3.2. 核心事務(wù)資源

    Vista開(kāi)始引入的TxF事務(wù)文件和TxR事務(wù)注冊(cè)表。可以對(duì)文件和注冊(cè)表進(jìn)行事務(wù)性操作。KTM可以管理這類資源。

    3.3. 傳統(tǒng)事務(wù)資源

    SQL Server 2000, Oracle, DB2, MSMQ這類資源是傳統(tǒng)的事務(wù)資源,這些資源只能由DTC事務(wù)管理器進(jìn)行管理。

    事務(wù)管理器可管理的事務(wù)資源:

    Resource

    LTM

    KTM

    DTC

    Sql Server事務(wù)資源

    Yes

    No

    Yes

    核心事務(wù)資源

    No

    Yes

    Yes

    傳統(tǒng)事務(wù)資源

    No

    No

    Yes

    4、 事務(wù)管理器的升級(jí)

    每個(gè)WCF中啟動(dòng)的事務(wù)都是先由LTM事務(wù)管理器管理,一旦事務(wù)中出現(xiàn)現(xiàn)有事務(wù)管理器無(wú)法管理的資源或情況,WCF會(huì)提升事務(wù)管理器的級(jí)別。分別從LTM升級(jí)到KTM,最高級(jí)別升級(jí)到DTC。事務(wù)管理器可以多次升級(jí),事務(wù)管理器一旦升級(jí)后不能降級(jí)。

    事務(wù)管理器的升級(jí)規(guī)則:

    image

    posted @ 2012-03-30 00:20 paulwong 閱讀(1560) | 評(píng)論 (0)編輯 收藏

    開(kāi)始Spring MVC

    建立一個(gè)web project,并導(dǎo)入spring 3.x的jar包配置web.xml根據(jù)上面的spring mvc流程圖,我們知道DispatcherServlet是spring mvc 的一個(gè)前端控制器,所以我們當(dāng)然要去配置它,以便于將請(qǐng)求轉(zhuǎn)給DispatcherServlet處理

      <servlet>
        
    <servlet-name>dispatcher</servlet-name>
        
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        
    <init-param>
            
    <param-name>contextConfigLocation</param-name>
    <!-- 如果配置文件位于classpath下,可以這么寫(xiě): classpath:dispatcher.xml -->
            
    <param-value>/WEB-INF/dispatcher.xml</param-value>
        
    </init-param>
        
    <load-on-startup>1</load-on-startup>
      
    </servlet>

      
    <servlet-mapping>
        
    <servlet-name>dispatcher</servlet-name>
        
    <url-pattern>/</url-pattern>
      
    </servlet-mapping>

    注:由于DispatcherServlet在初始化的過(guò)程中需要一個(gè)配置文件來(lái)生產(chǎn)文件中的各種bean,并生成WebApplicationContext對(duì)象,保存到ServletContext中(如果DispatcherServlet有多個(gè),那么每一個(gè)DispatcherServlet都對(duì)應(yīng)一個(gè)WebApplicationContext),我們可以在Servlet的init-param中配置配置文件的路徑,當(dāng)然如果我們沒(méi)有配置Init-Param,它會(huì)默認(rèn)到WEB-INF的文件夾中找[servletname]-servlet.xml文件,例如上面如果我們沒(méi)有配置,則會(huì)去尋找dispatcher-servlet.xml這個(gè)配置文件。(在init-param中我們可以指定多個(gè)配置文件,用逗號(hào)分隔也可以使用通配符*)
    配置上文中我們指定的所需的dispatcher.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context
    ="http://www.springframework.org/schema/context"
    xmlns:mvc
    ="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation
    ="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"
    >

        
    <context:component-scan base-package="com.controls" />
        
    <mvc:annotation-driven />
        
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
           
    <property name="prefix" value="/WEB-INF/views/"></property>
           
    <property name="suffix" value=".jsp"></property>
           
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>
        
    </bean>
    </beans>



    配置文件說(shuō)明:
    <context:component-scan base-package="com.controls" />
    由于我們使用了基于注解的Controller,所以這里指定了需要被掃描的包路徑,如果有多個(gè)可以使用逗號(hào)分隔
    <mvc:annotation-driven />

    上面的spring mvc流程圖中我們知道DispatcherServlet接管請(qǐng)求后,會(huì)由HandlerMapping來(lái)執(zhí)行映射,所以我們需要注冊(cè)HanlderMapping,比如上面的標(biāo)簽會(huì)自動(dòng)注冊(cè)比如DefaultAnnotationHandlerMapping(執(zhí)行請(qǐng)求到Controller的映射)和AnnotationMethodHandlerAdapter(調(diào)用controller中的方法)這樣的bean,當(dāng)然這個(gè)標(biāo)簽還提供了其他的一些支持(更多介紹請(qǐng)參照spring官方文檔第455頁(yè))。

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">

           
    <property name="prefix" value="/WEB-INF/views/"></property>

           
    <property name="suffix" value=".jsp"></property>

           
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"></property>

    </bean>

    上面spring mvc流程圖的最后controller處理完畢后會(huì)交給一個(gè)ViewResolver進(jìn)行處理,大體上是解析視圖邏輯名并經(jīng)過(guò)一定的處理獲取一個(gè)視圖,這里的意思是設(shè)置視圖用jsp來(lái)處理(比如我們?cè)O(shè)置viewClass為JstlView)來(lái)進(jìn)行處理,就是以forward的形式轉(zhuǎn)發(fā)給jsp,這個(gè)地址是:/WEB-INF/views/[controller返回值].jsp ,當(dāng)然視圖解析器可以定義多個(gè),(視圖解析器不會(huì)處理ModelAndView中已經(jīng)設(shè)置了View的請(qǐng)求,因?yàn)橐呀?jīng)有View來(lái)處理了,那當(dāng)然就不需要它來(lái)解析到真正的視圖View啦)
    編寫(xiě)Controller控制器這里我們使用例子的形式來(lái)說(shuō)明

    實(shí)現(xiàn)一個(gè)控制器類@Controller
    @Controller
    @RequestMapping(
    "/user")
    public class UserControl {

    }

    只要給類加上Controller的注解,并放在被掃描的包中,那么這個(gè)類就是一個(gè)控制器了,RequestMapping表明匹配的路徑,可以寫(xiě)在類或者類的方法上,如果類上面有RequestMapping注解,那么其下面的方法就是相對(duì)于類上面注解地址的一個(gè)相對(duì)路徑


    定義一個(gè)接管請(qǐng)求的方法方法名:無(wú)任何要求
    --------------------------------------------------------------
    參數(shù):(順序以及個(gè)數(shù)無(wú)任何要求)
    HttpServletRequest
    HttpServletResponse
    PrintWriter 相當(dāng)于HttpResponse.getWriter()獲得的對(duì)象
    Map 其實(shí)是獲得了ModelAndView中的Model
    BindingResult 綁定數(shù)據(jù)的處理結(jié)果
    HttpSession 如果使用此參數(shù),需要注意如果是第一次訪問(wèn)還沒(méi)有session的話會(huì)報(bào)錯(cuò)
    @PathVariable 用于接收路徑變量
    @RequestParam 相當(dāng)于調(diào)用request.getParameter(“name”)方法
    @CookieValue 獲取cookie的值
    @RequestHeader 獲取header中的值
    實(shí)體對(duì)象 會(huì)根據(jù)請(qǐng)求的參數(shù)名,注入到這個(gè)對(duì)象對(duì)于得屬性中,必須提供set方法
    等等等等等
    --------------------------------------------------------------
    返回值:
    void
    返回值是void,如果接收了PrintWriter 或者 HttpServletResponse 參數(shù),那么返回的ModelAndView就是null,也就是直接將輸出流輸出到客戶端,如果方法沒(méi)有接收輸出參數(shù),后面會(huì)默認(rèn)生成一個(gè)視圖名

    String 視圖邏輯名

    ModelAndView 是一個(gè)視圖邏輯名+Map的封裝類
    其他任意類型 存入ModelAndView中的Model
    --------------------------------------------------------------

    不管我們的返回類型是什么,返回值會(huì)通過(guò)處理,最終返回一個(gè)ModelAndView或者null
    例1:給方法定義一個(gè)請(qǐng)求映射并使用路徑變量 @RequestMapping("/id/{userid}/name/{username}")

    @RequestMapping("/id/{userid}/name/{username}")
    public String queryUser(@PathVariable("userid"long userID, @PathVariable("username") String userName, Map<String, User> model) {
           User user 
    = new User();
           user.setUserID(userID);
           user.setUserName(userName);
           model.put(
    "userInfo", user);
           
    return "Home";
        }


    @RequestMapping定義路由映射,其中{userid} {username} 是PathVariable(路徑變量)
    這樣我們只需訪問(wèn) http://localhost:8080/SpringMVC/user/id/10001/name/liudehua 就能進(jìn)入上面的方法
    RequestMapping還可以使用通配符,如: /test/*/name/{name}

    例2:接受請(qǐng)求參數(shù)@RequestMapping("/save")
    @RequestMapping("/save")
    public String save(@RequestParam("userName") String userName,@RequestParam("Age"int age) {
           System.out.println(userName);
           System.out.println(age);
           
    return "Home";
    }


    例3:請(qǐng)求參數(shù)直接注入到Model@RequestMapping("/save")
    @RequestMapping("/save")
    public String save(User user) {
           System.out.println(user.getUserID());
           System.out.println(user.getUserName());
           
    return "Home";
    }

    例4:轉(zhuǎn)發(fā)與重定向轉(zhuǎn)發(fā): (相當(dāng)于 request.getRequestDispatcher(“”).forward(request, response))
    return “forward:/user/test”;

    重定向: (相當(dāng)于response.redirect(“”))
    return “redirect:/user/test”
    return “redirect:http://www.google.com.hk”;

    例5:根據(jù)HttpMethod來(lái)過(guò)濾請(qǐng)求
    @RequestMapping(params="hello=world", method={RequestMethod.GET, RequestMethod.POST}
    public String helloworld() {
    }
     


    例6:根據(jù)參數(shù)來(lái)進(jìn)行過(guò)濾
    @RequestMapping(params="hello=world", method={RequestMethod.GET, RequestMethod.POST})  
    public String helloworld() {
    }
      

    必須有個(gè)hello的參數(shù)并且名稱為world,而且只能是get或post請(qǐng)求才會(huì)進(jìn)入此方法

    http://www.cnblogs.com/zhaoyang/archive/2012/01/07/2315425.html

    posted @ 2012-03-29 19:06 paulwong 閱讀(1160) | 評(píng)論 (0)編輯 收藏

    Joda-Time 簡(jiǎn)介

    假設(shè)我希望輸出這樣一個(gè)日期:距離 Y2K 45 天之后的某天在下一個(gè)月的當(dāng)前周的最后一天的日期。坦白地說(shuō),我甚至不想使用 Calendar 處理這個(gè)問(wèn)題。使用 JDK 實(shí)在太痛苦了,即使是簡(jiǎn)單的日期計(jì)算,比如上面這個(gè)計(jì)算。正是多年前的這樣一個(gè)時(shí)刻,我第一次領(lǐng)略到 Joda-Time 的強(qiáng)大。使用 Joda,用于計(jì)算的代碼如清單 3 所示:

    DateTime dateTime = new DateTime(2000, 1, 1, 0, 0, 0, 0);
    System.out.println(dateTime.plusDays(
    45).plusMonths(1).dayOfWeek() .withMaximumValue().toString("E MM/dd/yyyy HH:mm:ss.SSS");

    詳見(jiàn):
    http://www.oschina.net/question/12_7643

    posted @ 2012-03-27 17:09 paulwong 閱讀(297) | 評(píng)論 (0)編輯 收藏

    僅列出標(biāo)題
    共115頁(yè): First 上一頁(yè) 84 85 86 87 88 89 90 91 92 下一頁(yè) Last 
    主站蜘蛛池模板: 亚洲日韩乱码中文无码蜜桃臀网站| 思思re热免费精品视频66| 全部免费毛片在线| 亚洲av无码成人精品区一本二本| 国产无人区码卡二卡三卡免费| 亚洲福利一区二区三区| 最近中文字幕mv免费高清在线| 亚洲天堂在线播放| 100部毛片免费全部播放完整| 在线电影你懂的亚洲| 国产精品免费网站| 亚洲中文字幕AV每天更新| 日韩人妻无码免费视频一区二区三区| 亚洲精品国产首次亮相| 免费在线观看黄网| 最近更新免费中文字幕大全| 亚洲AV成人精品网站在线播放 | 亚洲情综合五月天| 一区二区三区无码视频免费福利| 亚洲精品自产拍在线观看动漫| 最近免费中文字幕mv在线电影 | 自拍偷自拍亚洲精品情侣| 18禁在线无遮挡免费观看网站| 亚洲精品在线不卡| 国产精品国产午夜免费福利看 | 亚洲精品美女久久久久久久| 免费国产小视频在线观看| 最近中文字幕免费大全| 亚洲理论片在线观看| 国产午夜无码视频免费网站| 国产日韩AV免费无码一区二区三区| 亚洲伦理一区二区| 免费视频中文字幕| 男人天堂免费视频| 亚洲三级中文字幕| 国产精品xxxx国产喷水亚洲国产精品无码久久一区 | 国产精品亚洲专区无码唯爱网| 自拍偷自拍亚洲精品情侣| 国产成人yy免费视频| xxxxxx日本处大片免费看 | 亚洲国产精品无码中文lv|