EJB事务回滚后自动重试

Eng*_*uad 4 java ejb weblogic jpa jakarta-ee

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

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

如果事务回滚,它是否会自动退出,直到事务完成?如果没有,如何启用?

dce*_*chi 5

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

\n\n
\n

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

\n
\n\n

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

\n\n

但通常最好捕获异常,MDB因为RuntimeExceptionMDB结果中抛出的异常会被容器丢弃。来自 EJB 3.1 规范:

\n\n
\n

一般来说,消息驱动 Bean 不应该抛出 RuntimeException。

\n\n

不是从消息驱动 bean 类的任何方法(包括消息侦听器方法和容器调用的回调)抛出的应用程序异常的 RuntimeException 会导致转换到 \xe2\x80\ x9c不存在\xe2\x80\x9d状态。

\n
\n\n

例如,最好有:

\n\n
public class MyMDB implements MessageListener {\n\n  @Resource\n  private MessageDrivenContext context;\n\n  public void onMessage() {\n     try {\n        //some other processing\n        someService.create(entity);\n     }\n     catch(Exception e) {\n        //mark the message as undelivered\n        context.setRollbackOnly();\n     }\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n