基本上,我有一个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");
}
}
如果事务被回滚,它是否会在事务完成之前自动退出?如果没有,如何启用?
答案 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();
}
}
}