2013-04-23 67 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