EJB 容器透過事務屬性定義方法執行時的事務邊界行為:是否加入現有事務、是否開啟新事務、或完全不使用事務。正確選型關係到資料一致性、效能與業務邏輯正確性。
| 屬性值 | 客戶端有事務 | 客戶端無事務 | 適用場景 |
|---|---|---|---|
| Required(預設) | 加入客戶端事務 | 開啟新事務 | 絕大多數業務方法,確保操作在事務保護下執行 |
| RequiresNew | 掛起客戶端事務 → 開啟新事務 → 執行 → 恢復原事務 | 開啟新事務 | 需獨立提交/回滾的操作(如審計日誌、獨立計費),與外層事務隔離 |
| Mandatory | 加入客戶端事務 | 拋出 TransactionRequiredException |
強制要求呼叫者提供事務上下文,防止無意識的無事務執行 |
| NotSupported | 掛起客戶端事務 → 無事務執行 → 恢復原事務 | 無事務執行 | 唯讀查詢、非關鍵操作,避免事務開銷提升效能 |
| Supports | 加入客戶端事務 | 無事務執行 | 可選事務支援,視呼叫者而定,靈活但需謹慎使用 |
| Never | 拋出 RemoteException |
無事務執行 | 嚴禁在事務中執行,防止長時間事務或資源鎖定 |
// Required:外層回滾 → 內層也回滾(同一事務)
// RequiresNew:外層回滾 → 內層已獨立提交,不受影響(不同事務)
關鍵差異: RequiresNew 建立獨立事務邊界,擁有自己的提交/回滾決策;Required 則共享外層事務命運。
ejb-jar.xml 或 @TransactionAttribute 註解配置,不硬編碼在業務邏輯中。誤區:「Required 表示一定會開啟新事務。」
正確:只有當客戶端無事務時才開啟新事務;若有現有事務則加入其中。
誤區:「NotSupported 會提交外層事務。」
正確:只是暫時掛起外層事務,不提交不回滾,方法結束後恢復。
掌握六大事務屬性的語義邊界,是設計健壯 EJB 應用的基石。實務上,Required 涵蓋 80%+ 場景,其餘屬性針對特定邊界條件設計。配合聲明式配置,可在不修改業務代碼的前提下靈活調整事務策略。