2013-04-23 57 views
3

基本上,我有一個JMS隊列和一個MDB來收集來自JMS隊列的消息,對它們進行一些處理,然後通過JPA將消息持久化到數據庫中。標誌着我的方法,它負責將持續到信息數據庫,在一個新的事務開始:EJB事務回滾後自動重試

@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
public void create(T entity) 
{ 
    try 
    { 
     getEntityManager().persist(entity); 
    } 
    catch(Exception e) 
    { 
     throw new RuntimeException("DB Exception"); 
    } 
} 

如果事務回滾,是走,直到交易完成時自動退休?如果沒有,如何啓用?

回答

4

如果異常傳播到MDB,事務將不會提交,消息將不會被確認爲收到並將被重試。來自EJB 3.1規範:

消息確認由容器自動處理。如果 消息驅動bean使用容器管理的事務 分界符,則消息確認自動作爲事務提交的一部分 處理。

我不熟悉Weblogic,但應該是設置的重試次數,重試間隔,等等,直到該消息被丟棄或放在未送達隊列中的JMS隊列參數。

但通常在MDB中捕獲異常更好,因爲從MDB拋出的RuntimeException導致bean被容器丟棄。來自EJB 3.1規範:

消息驅動bean通常不應拋出RuntimeExceptions。

一個RuntimeException不是來自 消息驅動bean類的任何方法拋出的應用程序異常(包括消息 偵聽方法和由容器調用的回調)在 結果過渡到「不存在「狀態。

例如,最好是有:「你的onMessage方法應該處理所有的異常拋出一個RuntimeException被認爲是一個編程錯誤」

public class MyMDB implements MessageListener { 

    @Resource 
    private MessageDrivenContext context; 

    public void onMessage() { 
    try { 
     //some other processing 
     someService.create(entity); 
    } 
    catch(Exception e) { 
     //mark the message as undelivered 
     context.setRollbackOnly(); 
    } 
    } 
} 
+0

在任何人需要參考的情況下:http://docs.oracle.com/javaee/7/tutorial/jms-concepts003.htm – mambolis 2017-02-06 19:13:58