EJB事务回滚后自动重试

时间:2013-04-23 18:16:38

标签: java java-ee jpa ejb weblogic

基本上,我有一个JMS队列和一个MDB来收集来自JMS队列的消息,对它们进行一些处理,然后通过JPA将消息保存到数据库中。我将负责将消息持久保存到DB中的方法标记为在新事务中启动:

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

如果事务被回滚,它是否会在事务完成之前自动退出?如果没有,如何启用?

1 个答案:

答案 0 :(得分:4)

如果异常传播到MDB,则事务将不会提交,消息将不会被确认为已接收并将被重试。来自EJB 3.1规范:

  

邮件确认由容器自动处理。如果   消息驱动的bean使用容器管理的事务   划分,消息确认作为一个部分自动处理   事务提交。

我不熟悉Weblogic但是应该有一个JMS队列参数来设置重试次数,重试间隔等,直到消息被丢弃或放在未传递的队列上。

但通常最好在MDB中捕获异常,因为从RuntimeException抛出的MDB会导致容器丢弃bean。来自EJB 3.1规范:

  

消息驱动的bean通常不应该抛出RuntimeExceptions。

     

不是从中抛出的应用程序异常的RuntimeException   消息驱动bean类的任何方法(包括消息   侦听器方法和容器调用的回调导致   过渡到“不存在”的状态。

例如,最好有:

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();
     }
  }
}