歷史痛點:早期版本為何被放棄?
- 無快取:每筆交易必訪問資料庫,叢集環境無快取可用
- 單表映射:O/R Mapping 過度簡化,無法應對複雜模型
- 單一 VM 單一實例:互斥鎖導致所有調用序列化,嚴重瓶頸
- 死鎖高風險:部分 Bean 用交易、部分不用時易死鎖
- 全欄位更新:
ejbStore 寫入所有欄位,無法偵測變更
- 全欄位載入:即使只需幾個欄位也全載入
- 無動態查詢:新查詢需重新部署
- 查詢實例化大量 Bean:記憶體壓力大、效能差
WebLogic 7.0 (EJB 2.0) 關鍵增強
- 容器管理關聯:一對一、一對多、多對多,雙向/單向
- 多表映射:單一 Entity Bean 映射多張 DB 表
- 優化寫入:
ejbStore 僅更新異動欄位
- 欄位組優化讀取:
ejbLoad 僅載入 field-group 指定欄位
- 關聯快取:聯合查詢快取載入關聯 Bean
- 支援 ejbSelect 回傳 ResultSet:多欄位查詢結果直接對應
- 應用級快取:多 Entity Bean 共享單一運行時快取
- 動態查詢:程式碼構造查詢無需重新部署
- Read-Mostly 設計模式:90% 讀 / 10% 寫場景最佳化
- 自動產生主鍵、級聯刪除、EJB QL、ejbSelect 方法
四大並行策略深度比較
| 策略 | 實例數 | 同步機制 | 適用場景 |
| Exclusive | 每 VM 單一 | 容器鎖序列化 | 極不推薦,效能差 |
| Database | 每交易一份拷貝 | 資料庫鎖 (交易開始/結束 ejbLoad/Store) | 一般預設,一致性高 |
| Read-Only | 每交易一份拷貝 | 無鎖,READ-TIMEOUT-SECONDS 控制 ejbLoad | 唯讀/極少寫,分散式快取最佳解 |
| Optimistic | 每交易一份拷貝 | 提交前檢查衝突 (版本/時間/修改欄位) | 可容忍短暫髒讀、需更新完整性 |
Optimistic 衝突檢測四選項
- 檢查讀取欄位
- 檢查修改欄位 (推薦)
- 檢查時間戳欄位 (需改表結構,不推薦)
- 檢查版本欄位 (需改表結構,不推薦)
可配置 cache-between-transactions=true 交易間快取,每筆交易開始仍呼叫 ejbLoad。
效能比較與選型建議
- 基準測試:未快取時,Stateless Session Bean + DAO (JDBC) 比 Entity Bean 快 30-50%
- 容器基礎設施優勢:優化 DB 存取、加速開發、簡化維護
- 何時用 Entity Bean:O/R 模型複雜 (多關聯)、重工程維護性 > 速度
- 何時用 JDBC:簡單原子更新、結合預存程序/觸發器、大量 ResultSet 處理
WebLogic 獨家殺手鐧
- Read-Mostly 模式:部署兩個 Bean (Read-Only + 一般),
<invalidate> 標記關聯,寫入時使唯讀 Bean 失效強制重載
- Optimistic + cache-between-transactions=true + verify-columns=Modified:可超越 JDBC 效能
以上屬性在 weblogic-ejb-jar.xml / weblogic-cmp-rdbms-jar.xml 設定,遷移其他 J2EE 伺服器無需改代碼。
結論
- 真實世界 90% 讀 / 10% 寫 → Read-Mostly 為最佳實踐
- 提供簡單開發、彈性部署、卓越讀取效能,僅寫入時有額外開銷
- Optimistic + 交易間快取可超越 JDBC
- 優化 SQL 難度高,勿忽視 Entity Bean 價值
範例與參考