API 層事務策略是最通用、最易實現、最健壯的事務模式,適用於絕大多數業務應用。其核心原則:所有事務邏輯集中在 API 層(Domain/Facade 層),客戶端層零事務責任。本文詳述架構、規則、限制、重構技巧與優化實現。

違反法則將導致:非擁有者標記回滾 → 擁有者無法感知、無法糾正、提交時拋異常 → 數據不一致。
| 方法類型 | 事務屬性 | 回滾邏輯 | 說明 |
|---|---|---|---|
| 公共寫方法 | REQUIRED | 必須包含(受檢異常回滾) | 事務擁有者候選 |
| 公共讀方法 | SUPPORTS | 無 | 若在事務中調用則加入,否則無事務 |
| 其他層所有方法 | 無 | 無 | 嚴禁事務註解/代碼 |
客戶端對單一 LUW 只能發起一次 API 層調用。若需多次調用,必須重構為聚合方法,否則違背黃金法則。




// 原始細粒度 API
@TransactionAttribute(REQUIRED)
public long insertTrade(TradeData trade) { ... }
@TransactionAttribute(REQUIRED)
public void updateAcct(TradeData trade) { ... }
// 重構:聚合方法成為唯一入口
@TransactionAttribute(REQUIRED)
public TradeData placeTrade(TradeData trade) {
try {
insertTrade(trade); // 內部調用,共享事務
updateAcct(trade);
return trade;
} catch (Exception up) {
ctx.setRollbackOnly();
throw up;
}
}
// 客戶端調用簡化為單次
public TradeData invokeClientRequest(TradeData trade) {
return placeTrade(trade); // 單一 API 調用
}
細粒度方法保留 REQUIRED 以支持獨立調用場景,聚合方法承擔事務擁有者角色。
若無法立即重構,可暫時在客戶端加程序化事務協調多 API 調用,但必須接受:
@Stateless
@Remote(TradingService.class)
@TransactionAttribute(TransactionAttributeType.REQUIRED) // 類級別默認
public class TradingServiceImpl implements TradingService {
@PersistenceContext(unitName="trading") EntityManager em;
@Resource SessionContext ctx;
public long insertTrade(TradeData trade) { // 繼承 REQUIRED
try {
em.persist(trade);
return trade.getTradeId();
} catch (Exception up) {
ctx.setRollbackOnly();
throw up;
}
}
@TransactionAttribute(TransactionAttributeType.SUPPORTS) // 覆蓋讀方法
public TradeData getTradeOrder(long tradeId) {
return em.find(TradeData.class, tradeId);
}
}
優勢:防止遺漏寫方法註解(默認有事務總比無事務強),讀方法顯式聲明 SUPPORTS 更清晰。
API 层策略以「簡單、統一、強一致性」著稱。團隊每位成員都應理解並遵循該策略。重構雖有成本,但換來的數據完整性與架構清晰度,長遠看極具回報。