今天我在EJB中發現了一些意外的行爲。我有默認交易屬性(REQUIRED
)和事務屬性設置爲REQUIRES_NEW
的SLSB的MDB。我的MDB調用SLSB並捕獲SLSB可能拋出的任何異常。當SLSB中發生某些真正的不良事件時,會拋出RuntimeException
的某個子類。然後,爲SLSB創建的新事務標記爲回滾。從我的角度來看,這是一個正確的行爲。然後,MDB捕獲此異常並執行一些操作(例如,寫一條消息以記錄日誌)並重新拋出。但MDB交易不知何故也成爲回滾的標誌,這對我來說似乎很陌生。這種行爲是否正確?EJB中的嵌套事務行爲
爲了更加精確,我可以寫類似於實際的一個了一些代碼,產生這種行爲:
@MessageDriven
public class A{
@EJB
private B b;
@Overried
public void onMessage(Message msg){
...
try{
b.process(msg);
} catch (Throwable t){
logger.error("Something gone wrong",t);
}
...
}
而且SLSB看起來是這樣的:
@EJB
@Stateless
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public class B{
public void process(Message msg){
...
}
}
有問題的任務流程是這樣的:
- 消息驅動bean
onMessage(Message)
被調用。 - 消息驅動bean執行一些操作成功,然後調用
B.process(Message)
方法。 - 發生了
B
錯誤,RuntimeException
被拋出。 RuntimeException
被封裝在EJBException
中,並被消息驅動bean成功捕獲。- 郵件驅動的豆
onMessage(Message)
方法被完全執行,但其交易標記爲回滾。
有人可以解釋這種行爲嗎? 在此先感謝。
您使用的是什麼appserver /版本?這個鏈接表明你的評估是正確的,因爲你的代碼應該工作:http://stackoverflow.com/questions/10817838/ejb-3-0-nested-transaction-requires-new。 – 2012-07-31 21:34:47
你也可以嘗試將兩個bean的*最小*例子放在一起 - 首先要確認你是否看到預期的行爲,並且刪除了所有其他「東西」,然後給其他人一些東西去玩另一個平臺。儘管這裏沒有承諾。 – 2012-07-31 21:55:37
我使用WebLogic 12c服務器。目前我無法提供任何可以組裝和部署的示例,但我會盡量在接下來的10-20小時內提供。也許我會在嘗試提供示例時發現問題。 :) – gkuzmin 2012-07-31 21:59:28