Sealyu

          --- 博客已遷移至: http://www.sealyu.com/blog

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            618 隨筆 :: 87 文章 :: 225 評(píng)論 :: 0 Trackbacks
          原貼網(wǎng)址: http://www.jdon.com/jivejdon/thread/34551.html
          最近注意了一下Seam文檔,牛人Gavin King的觀點(diǎn)貌似好多都曾出現(xiàn)在jdon,在jdon上混得久的人也許早就注意到了,下面貼文檔的一部分:

          有狀態(tài)Session Bean不僅可以在bean的多次調(diào)用之間保持狀態(tài),而且在多次請(qǐng)求之間也可以保持狀態(tài)。 不由數(shù)據(jù)庫保存的狀態(tài)通常應(yīng)該由有狀態(tài)Session Bean保持。這是Seam和其他web框架之間的一個(gè)顯著的不同點(diǎn)。 其他框架把當(dāng)前會(huì)話的信息直接保存在 HttpSession 中,而在Seam中你應(yīng)該把它們保存在有狀態(tài)Session Bean的實(shí)例中,該實(shí)例被綁定到會(huì)話上下文。這可以讓Seam來替你管理狀態(tài)的生命周期,并且保證在多個(gè)不同的并發(fā)會(huì)話中沒有狀態(tài)沖突。


          Seam是從Hibernate團(tuán)隊(duì)試圖生成典型的無狀態(tài)Java應(yīng)用架構(gòu)的挫折中成長起來的。 上一代Java應(yīng)用程序的無狀態(tài)特性讓Hibernate團(tuán)隊(duì)飽受挫折,Seam吸取了他們的經(jīng)驗(yàn)。 Seam的 狀態(tài)管理架構(gòu)最早是用來解決持久化沖突相關(guān)問題的,特別是 樂觀事務(wù)處理 相關(guān)的問題??蓴U(kuò)展的在線應(yīng)用經(jīng)常使用樂觀事務(wù)。 一個(gè)原子(database/JTA)級(jí)的事務(wù)不應(yīng)該跨用戶交互,除非系統(tǒng)設(shè)計(jì)時(shí)就是只支撐很少量的并發(fā)客戶端。 但幾乎所有涉及到的工作都是先將數(shù)據(jù)展現(xiàn)給用戶,沒多久后更新這個(gè)數(shù)據(jù)。所以Hibernate是依據(jù)支持一種跨樂觀事務(wù)的持久化上下文的思想設(shè)計(jì)的。

          不幸的是這個(gè)先于SeamEJB3.0出現(xiàn)的所謂“無狀態(tài)”架構(gòu)并不對(duì)樂觀事務(wù)進(jìn)行支持。而相反,這些架構(gòu)提供對(duì)于原子事務(wù)級(jí)的持久化上下文的支持。 這當(dāng)然給用戶帶來了很多麻煩,這也是用戶抱怨排名第一的Hibernate的 LazyInitializationException 問題的原因。 我們需要的是在應(yīng)用層構(gòu)建對(duì)于樂觀事務(wù)的支持。

          EJB3.0認(rèn)識(shí)到了此問題,并且也引入了有狀態(tài)組件(有狀態(tài)會(huì)話bean)的思想,它使用一個(gè) 擴(kuò)展持久化上下文來跟蹤組件的生命周期。 這是該問題的部分解決方案(對(duì)它自身而言也是一個(gè)有用的構(gòu)想),然而還有兩個(gè)問題:

          有狀態(tài)會(huì)話bean的生命周期必須在Web層通過代碼手動(dòng)管理(這是個(gè)麻煩的問題,而且實(shí)踐起來比聽上去更復(fù)雜)。

          在同一個(gè)樂觀事務(wù)的不同有狀態(tài)組件間,傳播持久化上下文是可行的,但很困難。

          Seam通過提供對(duì)話(Conversation)和對(duì)話期間的有狀態(tài)Session Bean組件來解決第一個(gè)問題(大多數(shù)會(huì)話實(shí)際上在數(shù)據(jù)層支持樂觀事務(wù))。 這對(duì)于很多不需要傳遞持久化上下文的簡單應(yīng)用(比如Seam的訂閱演示程序)已經(jīng)足夠了。 對(duì)于更復(fù)雜的在每一個(gè)對(duì)話中的有很多松耦合組件的應(yīng)用來說,組件間傳播持久化上下文就成為一個(gè)重要的問題了。 所以Seam擴(kuò)展了EJB 3.0的持久化上下文管理模型,以此來提供對(duì)話作用域的擴(kuò)展持久化上下文。



          數(shù)據(jù)庫成為了大多數(shù)企業(yè)應(yīng)用的主要瓶頸,也成為了運(yùn)行環(huán)境中最不具伸縮性的層。PHP/Ruby的用戶會(huì)說什么都不共享(share nothing)的架構(gòu)照樣具有很好的伸縮性。從表面上看也許是對(duì)的,可惜我不知道是否存在這樣的多用戶應(yīng)用,其實(shí)現(xiàn)是能夠在集群的 不同結(jié)點(diǎn)間不共享資源。這些傻瓜真正想的是“除了數(shù)據(jù)庫以外什么都不共享(Share nothing except for the database)”的架構(gòu)。當(dāng)然,共享數(shù)據(jù)庫是多用戶應(yīng)用伸縮性的主要問題——因此聲稱這樣的架構(gòu)具有高伸縮性是荒謬的,你可要知道它們花費(fèi)了這些人的 大部分時(shí)間。

          通常,幾乎所有通過共享數(shù)據(jù)庫做的事情并不值得這樣去做。

          這就是緩存(Cache)產(chǎn)生的原因。嗯,當(dāng)然并不只是一個(gè)緩存。一個(gè)設(shè)計(jì)良好的Seam應(yīng)用將具有豐富的多層緩存策略,這也影響著應(yīng)用的每一層:

          當(dāng)然,數(shù)據(jù)庫有它自己的緩存,這是超級(jí)重要的,但是它不能像應(yīng)用層的緩存一樣具有伸縮性。

          對(duì)從數(shù)據(jù)庫提取出的數(shù)據(jù),你的ORM解決方案(Hibernate,或者別的JPA實(shí)現(xiàn))具有兩級(jí)緩存。這是一種很強(qiáng)大的能力,但是經(jīng)常被誤用。在一個(gè)集群環(huán)境里,保持緩存中的數(shù)據(jù)在整個(gè)集群中具有事務(wù)一致性,并且和數(shù)據(jù)庫一致,其代價(jià)是相當(dāng)昂貴的。這對(duì)于共享在多個(gè)用戶間,且很少被更新的數(shù)據(jù)最有意義。在傳統(tǒng)的無狀態(tài)架構(gòu)里,人們經(jīng)常使用二級(jí)緩存來保存會(huì)話狀態(tài)。這種做法總是糟糕的,在Seam中更是大錯(cuò)特錯(cuò)的。

          Seam會(huì)話上下文是會(huì)話狀態(tài)的緩存。存儲(chǔ)于會(huì)話上下文中的組件可以保持并緩存與當(dāng)前用戶交互相關(guān)的狀態(tài)。

          特別的,Seam管理的持久化上下文(或者一個(gè)擴(kuò)展受管EJB容器持久化上下文,它與會(huì)話范圍的無狀態(tài)會(huì)話Bean相關(guān))成為了當(dāng)前會(huì)話中數(shù)據(jù)的緩存。這種緩存趨向于擁有一個(gè)相當(dāng)高的命中率!Seam優(yōu)化了集群環(huán)境中受管Seam持久化上下文的復(fù)制,也不需要保證數(shù)據(jù)庫事務(wù)的一致性(樂觀鎖已足夠),因此你不必?fù)?dān)心這種緩存的性能問題,除非你把成千上萬個(gè)對(duì)象讀取到一個(gè)單獨(dú)的持久化上下文中。

          應(yīng)用可以在Seam應(yīng)用上下文中緩存非事務(wù)性狀態(tài)。相應(yīng)的,保存在應(yīng)用上下文中的狀態(tài)不能被集群中其它結(jié)點(diǎn)訪問。

          應(yīng)用通過Seam的 pojoCache 組件可以緩存事務(wù)性狀態(tài),這個(gè)組件把JBossCache集成到了Seam環(huán)境中。如果你在集群模式下運(yùn)行了JBossCache,那么這個(gè)狀態(tài)是可以被別的結(jié)點(diǎn)訪問的。

          最后,Seam讓你能夠緩存生成的JSF頁面的部分內(nèi)容(rendered fragments)。與ORM的二級(jí)緩存不一樣的是,當(dāng)數(shù)據(jù)發(fā)生變化時(shí),這種緩存不能自動(dòng)的失效,因此你需要寫應(yīng)用代碼來使它顯式的失效,或者設(shè)置適當(dāng)?shù)倪^期策略。

          如要獲得更多關(guān)于二級(jí)緩存的信息,你可以參考你的ORM解決方案的文檔,因?yàn)檫@是個(gè)極為復(fù)雜的話題。在這節(jié)中我們會(huì)直接討論通過 pojoCache 組件使用JBossCache,或者通過 <s:cache>控制充當(dāng)頁片段(page fragment)緩存。

          EJB 會(huì)話Bean有聲明式事務(wù)管理功能。當(dāng)Bean被調(diào)用時(shí),EJB容器能夠透明地開始一個(gè)事務(wù),在調(diào)用結(jié)束時(shí)關(guān)閉此事務(wù)。 如果我們寫了一個(gè)作為JSF動(dòng)作監(jiān)聽器的會(huì)話Bean方法,我們就可以在一個(gè)事務(wù)內(nèi)處理所有與此action相關(guān)的工作,并且當(dāng)我們完成此動(dòng)作處理時(shí)事務(wù) 必須被提交或回滾。 這是一個(gè)很棒的功能,在很多Seam應(yīng)用程序中這是必需的。

          但是,此方法還是有問題。Seam應(yīng)用可能無法在對(duì)會(huì)話Bean的一次方法調(diào)用請(qǐng)求中完成所有的數(shù)據(jù)訪問。

          此請(qǐng)求可能由幾個(gè)松耦合組件處理,Web層獨(dú)立地調(diào)用每一個(gè)組件。在Seam中,Web層的一個(gè)請(qǐng)求對(duì)EJB組件發(fā)起幾次甚至多次調(diào)用的現(xiàn)象是很常見的。

          視圖渲染可能需要延遲關(guān)聯(lián)獲取(lazy fetching of associations)。

          每個(gè)請(qǐng)求的事務(wù)量越多,當(dāng)我們的應(yīng)用處理大量并發(fā)請(qǐng)求時(shí)越可能碰到原子和隔離問題。當(dāng)然,所有的寫操作要在一個(gè)事務(wù)中執(zhí)行。

          Hibernate用戶開發(fā)了 "Open Session in View" 模式來解決該問題。 在Hibernate社區(qū),"Open Session in View"曾經(jīng)非常重要,這是因?yàn)橄?a class="hotkeys ajax_query=Spring" id="id_http://www.jdon.com/dl/best/spring.htm">Spring這樣的框架使用了事務(wù)作用域持久化上下文。 所以當(dāng)未獲得的關(guān)聯(lián)被訪問時(shí)渲染視圖將引起 LazyInitializationException 異常。

          這 個(gè)模式通常作為一個(gè)跨越整個(gè)請(qǐng)求的事務(wù)來實(shí)現(xiàn)。 此實(shí)現(xiàn)方式會(huì)有幾個(gè)問題,其中最嚴(yán)重的是只有我們提交了事務(wù)才能確認(rèn)它成功完成——但在"Open Session in View"的事務(wù)提交時(shí),視圖已經(jīng)完全渲染了,甚至渲染好的應(yīng)答可能已經(jīng)刷新到客戶端。我們?cè)鯓硬拍芡ㄖ脩羲麄兊氖聞?wù)已失敗呢?

          Seam在解決"Open Session in View"問題時(shí),也解決了事務(wù)隔離和關(guān)聯(lián)獲取問題。該方案有有兩個(gè)部分:

          使用使用已擴(kuò)展持久化上下文,可以覆蓋一個(gè)會(huì)話作用域而不是單個(gè)事務(wù)作用域。

          每次請(qǐng)求使用兩個(gè)事務(wù);第一個(gè)從更新模型值的起始階段到應(yīng)用程序調(diào)用結(jié)束;第二個(gè)跨越渲染響應(yīng)階段。

          很多應(yīng)用服務(wù)器的 HttpSession 集群實(shí) 現(xiàn)都有問題,對(duì)綁定到Session的可變對(duì)象狀態(tài)的改變只有在明確調(diào)用 setAttribute() 的時(shí)候才會(huì)被復(fù)制。 這是Bug的一個(gè)源頭,這些Bug難以在開發(fā)階段有效找出,因?yàn)樗鼈冎粫?huì)在應(yīng)用服務(wù)器失效切換的時(shí)候才會(huì)被發(fā)現(xiàn)。 而且,實(shí)際的復(fù)制信息包含了綁定到Session的所有序列化對(duì)象圖,這是低效的。
          當(dāng)然,EJB 有狀態(tài)Session Bean必須進(jìn)行自動(dòng)dirty checking,并進(jìn)行可變狀態(tài)的復(fù)制,并且EJB 容器也應(yīng)該引入優(yōu)化,例如屬性級(jí)別的復(fù)制。 但不幸的是,并非所有的Seam用戶都有這么好的運(yùn)氣,他們的環(huán)境可能并不支持EJB 3.0。 因此,對(duì)于Session和Conversation范圍內(nèi)的JavaBean和Entity Bean組件,在Web容器的Session集群之上,Seam提供了額外的集群安全的狀態(tài)管理層。
          posted on 2009-03-27 12:08 seal 閱讀(300) 評(píng)論(0)  編輯  收藏 所屬分類: Seam
          主站蜘蛛池模板: 阜宁县| 邢台市| 吴川市| 临沭县| 通辽市| 福泉市| 遂川县| 甘德县| 罗江县| 淮南市| 资兴市| 宣威市| 龙岩市| 广安市| 固安县| 平果县| 台东市| 沙河市| 文安县| 甘德县| 壤塘县| 张家界市| 彭阳县| 乌拉特中旗| 威宁| 天津市| 密山市| 原平市| 河源市| 平原县| 德江县| 准格尔旗| 新晃| 开原市| 红河县| 巍山| 稷山县| 平阳县| 略阳县| 鸡泽县| 霸州市|