Java EJB事务回滚后自动重试

Java EJB事务回滚后自动重试,java,jakarta-ee,jpa,ejb,weblogic,Java,Jakarta Ee,Jpa,Ejb,Weblogic,基本上,我有一个JMS队列和一个MDB来收集来自JMS队列的消息,对它们进行一些处理,然后通过JPA将消息持久化到数据库中。我将负责将消息持久化到DB中的方法标记为在新事务中启动: @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public void create(T entity) { try { getEntityManager().persist(entity); }

基本上,我有一个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");
    }
}

如果事务回滚,在事务完成之前它是否将自动失效?如果没有,如何启用该功能?

如果异常传播到
MDB
,事务将不会提交,消息将不会被确认为已接收,并将重试。根据EJB3.1规范:

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

我不熟悉
Weblogic
,但应该有一个JMS队列参数,用于设置重试次数、重试间隔等,直到消息被丢弃或放入未送达的队列

但是通常最好在
MDB
中捕获异常,因为从
MDB
抛出的
RuntimeException
会导致bean被容器丢弃。根据EJB3.1规范:

消息驱动bean通常不应该抛出运行时异常

不是从中引发的应用程序异常的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();
     }
  }
}

“您的onMessage方法应处理所有异常。引发RuntimeException被视为编程错误。”如果任何人需要引用: