在 Spring 框架中,事務傳播行為定義了當一個事務方法被另一個事務方法調用時,事務如何傳播與邊界劃分。TransactionDefinition 介面定義了七種傳播行為常量,掌握它們是處理複雜事務場景的基礎。
假設調用鏈:Consumer → methodA() → methodB(),雙方傳播屬性均為 REQUIRED。
public void methodA() {
try {
methodB();
} catch (Exception e) {
process(); // 處理異常但未重新拋出
}
otherOperation();
}
當 methodB 拋出異常時,共享事務被標記為 rollback-only。雖然 methodA 捕獲了異常並正常執行完畢,但 Spring 在提交事務時發現事務已被標記回滾,因而拋出 UnexpectedRollbackException: "Transaction rolled back because it has been marked as rollback-only"。
REQUIRED 傳播下,methodA 與 methodB 共用同一個物理事務。methodB 異常導致事務標記為僅回滾,而 methodA 未感知並嘗試正常提交,引發衝突。
讓 methodA 不參與事務管理,避免提交衝突。
methodB 開啟新事務並掛起外部事務,內部異常回滾不影響外部事務狀態。
通過多次調用 methodB 並捕獲異常測試發現:事務被標記回滾後,後續操作仍可正常執行(如打印語句),推測 Spring 內部對已回滾事務的再次回滾操作採用「跳過」策略,不會重複執行回滾邏輯。
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly())。REQUIRES_NEW。NESTED)僅適用於 JDBC 數據源,且依賴數據庫對 Savepoint 的支援。