當 Bean 宣告事務控制為 TX_BEAN_MANAGED,即進入 Bean 管理事務 (BMT) 模式。本文系統解析 BMT 核心 API、會話同步介面、事務狀態標記機制、客戶端劃分事務、資料庫操作事務邊界、分布式事務支撐六大維度,還原容器與 Bean 協同管理事務的精密機制。
Bean 透過 setSessionContext() 或 setEntityContext() 獲取 SessionContext/EntityContext(均繼承 EJBContext),關鍵方法:
public interface javax.ejb.EJBContext {
public UserTransaction getUserTransaction() throws IllegalStateException;
public boolean getRollbackOnly();
public void setRollbackOnly();
// 其他:getCallerIdentity, isCallerInRole, getEJBHome, getEnvironment
}
獲取 UserTransaction 後,Bean 可自主控制事務邊界:begin()、commit()、rollback()、setRollbackOnly()、getStatus()。
限制:無狀態會話 Bean 與實體 Bean 不允許 跨方法保持事務活躍(容器會拋出例外),因無狀態/實體 Bean 本質無會話狀態。
有狀態/無狀態會話 Bean 實作 javax.ejb.SessionSynchronization 介入容器管理事務:
public interface javax.ejb.SessionSynchronization {
public void afterBegin() throws RemoteException; // 事務開始,進入業務方法前
public void beforeCompletion() throws RemoteException; // 事務提交前,寫入資料庫等
public void afterCompletion(boolean committed) throws RemoteException; // 提交/回滾後通知
}
運作流程:
afterBegin() → Bean 記錄「在事務中」標記。beforeCompletion()(回滾時不呼叫)。afterCompletion(committed) → Bean 清除標記、修正內部狀態。關鍵規則:實作此介面暗示 Bean 跨方法保持事務狀態,無狀態 Bean 禁用(安裝工具應檢測報錯)。有狀態 Bean 可選擇不實作,但需在部署描述符精確配置事務屬性確保正確性。
定義於 EJBContext 與 UserTransaction,所有 Bean 可用(不限 BMT):
setRollbackOnly():投票要求當前事務最終回滾(單向標記,不可撤銷)。getRollbackOnly():檢查事務是否已被標記回滾,避免執行將被逆轉的強制性操作(如資料庫更新)。設計為無參數單向方法,防止 Bean 互相干擾回滾投票。
大型伺服器廠商可能提供 Current 類讓客戶端直接存取事務管理器:
Current current = new Current();
current.setServiceProvider(txMgrURL);
current.begin();
// 在兩台不同伺服器的 Bean 上呼叫業務方法,事務上下文隱式傳播
RemRef1.doSomeWork();
RemRef2.doMoreWork();
current.commit();
Stub/Skeleton 支援事務上下文隱式傳遞,實現跨 JVM 事務邊界統一。
SessionSynchronization 硬性合併。分布式事務觸發場景:
廠商必須為 EJBObject 生成的 Stub/Skeleton 實現:隱式獲取當前事務上下文 → 方法調用攜帶傳遞 → 遠端 Skeleton 接收並登記至本地事務管理器。這是 EJB 容器分布式事務透明化的基礎設施。
BMT 賦予 Bean 事務邊界完全控制權,但責任對等。SessionSynchronization 讓 Bean 參與容器管理事務生命週期,setRollbackOnly 提供投票式回滾機制。分布式事務依賴容器生成的 Stub/Skeleton 實現上下文隱式傳播,JDBC 連接透明登記實現資源管理器協調。掌握這些機制,方能駕馭複雜企業級事務場景。