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

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

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

    posts - 56, comments - 77, trackbacks - 0, articles - 1
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    ORM問題域

    Posted on 2009-12-28 23:49 切爾斯基 閱讀(1981) 評論(0)  編輯  收藏

    假設我們必須處理對象的存儲, 加載, 和查詢. 性能和引用完整性的約束, 給接口的實現帶來了以下問題:

    1. 加載根對象時如何避免加載大半個數據庫

    2. 存儲時如何更新整個對象圖

    3. 存儲時如何高效的更新整個對象圖

    4. 何時同步對象的內存狀態和持久存儲狀態

    5. 如何確保在出錯時保持對象內存狀態和持久存儲狀態之間的一致性

    6. 如何保證引用的唯一性以避免可能的更新沖突

    對性能的精益求精, 又促使人們解決更多的細節問題:

    1. N+1查詢問題

    2. 分離查詢模型和存儲模型

    3. 盡量減少查詢語句

    這些問題的解決方案又會帶來新的問題.

     

    1. 加載根對象時如何避免加載大半個數據庫

    更多的時候這是一個建模問題, 為什么我只需要顯示一點信息, 更新一點信息, 卻拉家帶口把八桿子打不著的親戚都帶上 : 細粒度對象設計, 直接訪問需要的信息, 減少所謂根對象的存在

    一個workaround是延遲加載, 當你無法修復你錯誤的建模時, 當真正去訪問子對象的時候再發出查詢語句去加載. 這個方案會帶來如下問題:

    1. 查詢語句較多. 無解, 延遲意味著至少兩條SQL語句, 只能盡量減少

    2. 延遲加載的時機, 是自動透明的延遲加載, 還是用戶確定何時加載

    Hibernate可通過配置文件指定是否lazy load, 一旦指定, 后面的load就是透明的在訪問子對象時發生. 也可在發出每次查詢時顯式指定

    Entity Framework則要求用戶在每一次查詢時顯式指定包含哪個子對象, 對沒有指定包含的子對象, 只能在訪問前顯示使用load(). 理由是決定加載不加載,何時加載都是程序員的責任

    1. 然而更大的問題是如何管理數據庫連接, 要確保延遲加載的時候數據庫連接是開著的

    可以使用Interceptor等技術維持 Session per request, Open Session in View pattern(處理好異常等, 確保session會關閉).

    能在一個 Session 中使用兩個事務嗎?

    是的,這事實上是這種模式(Open Session In View)的一個更好的實現。在一個請求事件中,一個數據庫事務用于數據的讀寫。第二個數據庫事務僅用于在渲染視圖期間讀數據。在這點上沒有對對象的修改。因此,數據庫鎖早在第一個事務時就被釋放了,這使得應用有更好的可伸縮性,第二個事務可以被優化。要使用兩階段的事務,你需要比 Servlet Filter 更強大的攔截器 - AOP 是個很好的選擇。JBoss Seam 使用了這種模式。

    為什么 Hibernate 不在需要時就加載 Object?

    每個月很多人都會有這種想法,為什么 Hibernate 不能在有需要的就開啟一個新的數據庫連接(更有效率的是開啟一個 Session),然后加載集合或是初始化代理,而是選擇拋出一個 LazyInitializationException。當然,這種想法,第一眼看上去可能是明智之舉。但這種做法有很多的缺點,只有當你考慮特別的事務訪問時才會發現。

    如果 Hibernate 可以進行任意的數據庫連接和事務,這種操作是開發人員不可知,并且也是在任何事務邊界之外的,那還要事務邊界做什么。當 Hibernate 開啟了新的數據庫連接去加載集合,但同時集合的擁有者卻被刪除了,這是將會發生什么?(注意,這種情況是不會發生在上面提到的兩階段的事務模式中的 - 單個 Session 可對實體可重復讀。)當所有的對象都可以通過關聯導航獲取時為什么還要有 Service 層?這種方式將消耗多少內存?哪些對象要首先被清除掉?所有這些問題都是無解的,因為 Hibernate 是一個在線的事務處理服務(并包含一些批處理操作),并不是一個“在未定義的工作單元中從數據持久倉庫取得對象”的服務。此外,對于 n+1 查詢問題,我們是否需要 n+1 的事務和連接的問題?

    這個問題的解決方案當然是正確的工作單元劃分和設計,支撐其的攔截技術就像這里所展現的一樣,并且/或者正確的抓取技術,使得特定工作單元所需的全部信息能夠以最小的影響、最好的性能和伸縮性被獲得。

     

    2. 存儲時如何更新整個對象圖

    框架支持級聯更新. 是否應該級聯更新, 哪些操作可以級聯, 哪些不可以, 對象之間的哪些類型的關聯可以級聯, 哪些不可以, 則是程序員的責任

    • 通常被聚合的對象, 其生命周期應由父對象負責, 新增/更新/刪除都應級聯

    • 自身有存在意義的實體, 可以級聯更新, 但不應刪除和新增

     

    3. 存儲時如何高效的更新整個對象圖

    常用工作單元模式, Unit of Work.

     

    4. 何時同步對象的內存狀態和持久存儲狀態

    任何改動都立即提交到數據庫會帶來額外開銷. 一個時機是事務提交時.

    Hibernate: 每間隔一段時間,Session會執行一些必需的SQL語句來把內存中的對象的狀態同步到JDBC連接中。這個過程被稱為刷出(flush),默認會在下面的時間點執行:

    • 在某些查詢執行之前

    • 在調用org.hibernate.Transaction.commit()的時候

    • 在調用Session.flush()的時候

     

    5. 如何確保在出錯時保持對象內存狀態和持久存儲狀態之間的一致性

    數據庫事務回滾, 清空內存緩存, 重新加載

     

    6. 如何避免或處理可能的更新沖突

    保證引用的唯一性: 使用單一的加載入口和緩存, Identity Map.

    樂觀離線鎖會引入更新沖突問題, 一般使用Versioning來解決, 類似版本控制系統的更新問題; 但業務對象很少能自動Merge, Merge的語義也不好定義, 所以一般檢測到沖突之后只好重做了, 或者取決于業務邏輯, Last Win也是一種策略.

     

    7. N+1查詢問題

    • Eager Load + JOIN

    • 截然不同的一種避免N+1次查詢的方法是,使用二級緩存。

    N + 1 是關聯引入的問題, 網上的解釋和例子傾向于拿one-2-many說事, 但實際上one-2-one依然面臨使用多于一條SQL語句加載的問題

     

    8. 分離查詢模型和存儲模型

    適合業務關系的對象模型未必對查詢是高效的. 需要單獨針對查詢建模, 可以用單獨的索引表來實現. 在更新業務對象的存儲時同時更新索引表

     

    9. 盡量減少查詢語句

    比如join over multiple select, 比如批量抓取

     

    10. 值類型

    不需要有ID, 通常被聚合. 有對應的Class, 但一般沒有對應的Table, 僅是Table中的幾個字段

    挑戰在于將對象語言類型系統(和開發者定義的實體和值類型)映射到 SQL/數據庫類型系統。 Hibernate: 提供了連接兩個系統之間的橋梁:對于實體類型,我們使用class, subclass 等等。對于值類型,我們使用 property, component 及其他,通常跟隨著type屬性。這個屬性的值是Hibernate 的映射類型的名字


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 丁香花在线观看免费观看| 91禁漫免费进入| 四虎永久免费观看| 亚洲色偷偷色噜噜狠狠99| 国产大片线上免费观看 | 久久国产精品国产自线拍免费| 亚洲国产aⅴ综合网| 黄色a三级三级三级免费看| 亚洲高清无码综合性爱视频| 亚美影视免费在线观看| 亚洲综合无码AV一区二区| 两个人日本免费完整版在线观看1| 亚洲一区二区高清| 七色永久性tv网站免费看| 亚洲色图在线观看| 免费无码AV片在线观看软件| 亚洲AV永久无码天堂影院| 亚洲AV无码一区二区三区在线观看 | 在线观看免费高清视频| 亚洲砖码砖专无区2023| 免费h成人黄漫画嘿咻破解版| 国产精品成人免费观看| 久久亚洲精品无码| 在线视频免费观看高清| 色九月亚洲综合网| 亚洲精品美女久久久久99| 国产成人精品免费视频大| 污视频在线观看免费| 亚洲激情校园春色| 色吊丝最新永久免费观看网站| 国产成人精品亚洲日本在线| 亚洲性线免费观看视频成熟 | 免费看美女被靠到爽的视频| 免费人成网站永久| 亚洲AV无码不卡在线播放| 成人影片麻豆国产影片免费观看| 在线观看亚洲精品专区| 亚洲男人第一av网站| 国产精品色午夜免费视频| 久久免费观看国产99精品| 亚洲爆乳无码精品AAA片蜜桃|