Hibernate 直接使用 JDBC/JTA,**不添加額外鎖定、不改變隔離級別**,僅提供自動版本管理。使用體驗接近原生 JDBC,但消除了樣板代碼。強烈建議先掌握 JDBC 事務、ANSI SQL 隔離級別、目標數據庫鎖行為。
Configuration 創建一次,所有線程共享openSession()/close()長事務持有鎖導致併發度下降,擴展性受限。原則:事務邊界盡可能貼近業務操作。
單次 DB 調用開關 Session — **極其低效**,破壞事務原子性。Hibernate 禁用 JDBC auto-commit。
**多用戶 Client/Server 最常用**:
flush() + commit()一請求一 Session 一事務,1:1:1 對應。實現關鍵:
OpenSessionInViewFilter / EJB 攔截器,在請求進入/離開時管理 Session此模式稱 ThreadLocal Session 或 Open Session in View。
長事務持鎖 → 併發崩潰。**絕對禁止**。
只有最後提交事務寫入數據,前序事務僅讀取。Hibernate 三大特性支撐:
| 模式 | 核心機制 | 優點 | 缺點 |
|---|---|---|---|
| session-per-request-with-detached-objects | 請求間對象脫管,saveOrUpdate/merge 重新關聯,自動版本檢查 | Session 輕量、無長連接、適合 Web 無狀態 | 需管理脫管狀態、合併邏輯 |
| session-per-application-transaction (Long Session) | 單 Session 跨請求,disconnect()/reconnect() 斷開/恢復連接,自動版本檢查 | 無重新加載、最高效 DB 訪問、對象身份保證 | Session 累積髒數據大、不宜序列化傳 Web 層、需狀態 EJB 持有 |
| 應用級版本檢查 | 每次新 Session 手動重新加載比較版本 | 概念簡單 | 效率最低、代碼冗長、不推薦 |
foo.getId().equals(bar.getId())foo == barfoo == bar ⇔ 同一行數據foo != bar),但 foo.getId().equals(bar.getId())不要用數據庫 ID 實現 equals/hashCode (瞬時對象 ID 為 null,持久化後改變,破壞 Set/Map 契約)。
使用業務鍵:唯一、通常不變的業務屬性組合 (如用戶名、郵箱、產品代碼)。只需保證同一集合內對象業務鍵穩定。
clear()/evict()、批量操作用無狀態 Session/存儲過程 (第14章)begin/commit/rollbackSession 同步可自動Transaction API 封裝底層差異 (除 CMT 外強烈推薦)flush)下一章將詳細展開托管/非托管環境下的具體代碼模式與異常處理細節。