首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

EJB Bean 管理事務 (BMT) 深度解析:UserTransaction、SessionSynchronization 與分布式事務協調

     編輯:Java 相關知識

當 Bean 宣告事務控制為 TX_BEAN_MANAGED,即進入 Bean 管理事務 (BMT) 模式。本文系統解析 BMT 核心 API、會話同步介面、事務狀態標記機制、客戶端劃分事務、資料庫操作事務邊界、分布式事務支撐六大維度,還原容器與 Bean 協同管理事務的精密機制。

核心 API:EJBContext 與 UserTransaction

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 與實體 Bean 不允許 跨方法保持事務活躍(容器會拋出例外),因無狀態/實體 Bean 本質無會話狀態。

SessionSynchronization:容器回調 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; // 提交/回滾後通知
}

運作流程:

  1. 事務線程進入 Bean → 容器呼叫 afterBegin() → Bean 記錄「在事務中」標記。
  2. 容器提交前 → 呼叫 beforeCompletion()(回滾時不呼叫)。
  3. 事務結束 → 呼叫 afterCompletion(committed) → Bean 清除標記、修正內部狀態。

關鍵規則:實作此介面暗示 Bean 跨方法保持事務狀態,無狀態 Bean 禁用(安裝工具應檢測報錯)。有狀態 Bean 可選擇不實作,但需在部署描述符精確配置事務屬性確保正確性。

事務狀態標記:setRollbackOnly / getRollbackOnly

定義於 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 事務邊界統一。

資料庫操作事務邊界:JDBC 連接的隱式登記

  • Bean 使用 JDBC 連接時,禁用 auto-commit,不得手動 commit/rollback。
  • 容器決定事務最終提交或回滾。
  • 機制:JDBC 驅動在連接建立時,透明登記至執行緒當前事務(OTS 不可恢復資源模型)。容器結束事務時,連接自動跟隨結束。
  • 若使用非事務感知驅動,開發者須自行管理連接事務,不可靠且不建議 透過 SessionSynchronization 硬性合併。

分布式事務支撐:Stub/Skeleton 隱式上下文傳播

分布式事務觸發場景:

  1. 客戶端劃分事務跨多伺服器多 Bean 調用。
  2. Bean 方法調用遠端伺服器其他 EJB。

廠商必須為 EJBObject 生成的 Stub/Skeleton 實現:隱式獲取當前事務上下文 → 方法調用攜帶傳遞 → 遠端 Skeleton 接收並登記至本地事務管理器。這是 EJB 容器分布式事務透明化的基礎設施。

總結

BMT 賦予 Bean 事務邊界完全控制權,但責任對等。SessionSynchronization 讓 Bean 參與容器管理事務生命週期,setRollbackOnly 提供投票式回滾機制。分布式事務依賴容器生成的 Stub/Skeleton 實現上下文隱式傳播,JDBC 連接透明登記實現資源管理器協調。掌握這些機制,方能駕馭複雜企業級事務場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved