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

EJB 事務屬性全解析:六大傳播行為的選型指南

     編輯:Java 相關知識

EJB 容器管理事務 (CMT) 通過聲明式事務屬性定義方法邊界的事務傳播行為。正確選擇六大屬性 (Required、RequiresNew、Mandatory、NotSupported、Supports、Never) 是保證數據一致性與性能的關鍵。本文結合流程圖與決策矩陣,提供生產級選型指南。

六大屬性行為對照表

屬性客戶端有事務客戶端無事務典型場景
Required (默認)加入現有事務開啟新事務90% 業務方法,增刪改查通用
RequiresNew掛起現有 → 開啟新 → 完成後恢復開啟新事務獨立提交:日志記錄、審計、郵件發送
Mandatory加入現有事務拋出 TransactionRequiredException強制要求外層事務:核心業務邏輯、不可獨立執行
NotSupported掛起現有 → 無事務執行 → 恢復無事務執行只讀查詢、長耗時計算、外部 API 調用
Supports加入現有事務無事務執行輔助工具方法、可選事務上下文
Never拋出 RemoteException無事務執行嚴禁事務:特定報表查詢、非事務性資源訪問

決策流程圖 (文字版)

方法是否修改數據?
├─ 是 → 是否必須在獨立事務提交?(如日志、審計)
│   ├─ 是 → RequiresNew
│   └─ 否 → 是否允許無事務調用?
│       ├─ 否 (核心業務) → Mandatory
│       └─ 是 (通用增刪改) → Required
└─ 否 (只讀/輔助)
    ├─ 是否為長耗時/外部調用? → NotSupported
    ├─ 是否嚴禁事務上下文? → Never
    └─ 其他 → Supports

常見誤區與最佳實踐

  1. 誤以為 Required 總是開啟新事務:實際上它優先加入現有事務,僅在無事務時創建
  2. 濫用 RequiresNew 導致事務碎片化:每個獨立事務意味著獨立的資源連接、鎖、提交開銷,高併發下易耗盡連接池
  3. 忽視 NotSupported 的性能紅利:大報表查詢、批量只讀操作掛起事務可顯著降低數據庫鎖爭用
  4. 異常回滾規則:默認僅 RuntimeException 觸發回滾,檢查型異常需 @ApplicationException(rollback=true) 或 setRollbackOnly()

注解與 XML 雙重配置示例

// 注解方式 (EJB 3.0+)
@Stateless
public class OrderService {
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void createOrder(Order order) { ... }

    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    public void logAudit(AuditRecord record) { ... }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List searchProducts(SearchCriteria c) { ... }
}

// ejb-jar.xml 覆蓋
<assembly-descriptor>
  <container-transaction>
    <method>
      <ejb-name>OrderService</ejb-name>
      <method-name>createOrder</method-name>
    </method>
    <trans-attribute>Required</trans-attribute>
  </container-transaction>
</assembly-descriptor>

嵌套調用事務傳播實例

// 客戶端無事務
orderService.createOrder(order); 
  // → 開啟事務 T1 (Required)
  //   orderDAO.save(order);      // 加入 T1
  //   auditService.log(record);  // RequiresNew → 掛起 T1,開啟 T2 提交,恢復 T1
  //   inventoryService.reserve(); // Mandatory → 加入 T1 (若 T1 被掛起則異常)
  // → T1 提交

遷移至 Spring @Transactional 映射對照

EJB 屬性Spring propagation備註
RequiredPROPAGATION_REQUIRED默認值一致
RequiresNewPROPAGATION_REQUIRES_NEW行為一致
MandatoryPROPAGATION_MANDATORY行為一致
NotSupportedPROPAGATION_NOT_SUPPORTED行為一致
SupportsPROPAGATION_SUPPORTS行為一致
NeverPROPAGATION_NEVER行為一致

掌握六大屬性語義,結合業務邊界設計事務策略,是構建健壯企業級應用的核心基本功。

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