@MessageDriven事务和重新传递语义

时间:2011-12-31 17:33:53

标签: glassfish jms glassfish-3 ejb-3.1 message-driven-bean

完成以下任务的最佳方式是什么?

  • @MessageDriven bean在数据库上做了一些工作
  • 失败时,我想回滚数据库事务
  • 但我也希望JMS消息不被重新传递,即不要重新尝试。

我可以想到可能工作的几种方式。还有其他人,哪个最好?

  • 使用@TransactionManagement(type=BEAN)UserTransaction,并在捕获异常后显式回滚。 e.g:

    catch (Exception e) { e.printStackTrace(); utx.rollback(); }

  • 使用容器管理的事务,在@TransactionAttribute(value=NOT_SUPPORTED)上指定onMessage,然后将数据库活动委托给使用@TransactionAttribute(value=REQUIRED)的单独方法。

  • 单独保留事务处理并重新配置服务器中的重试属性。我正在使用Glassfish 3.1.1,我不确定如何设置它。

  • 单独保留所有内容并明确检查邮件是否在onMessage正文中重新发送,如果重新发送则退出。 (message.getJMSRedelivered()?)

那里运作得很好?是否有处理此问题的标准/最佳实践方法?

2 个答案:

答案 0 :(得分:8)

最简单,最便携的方法是在@TransactionAttribute(value=NOT_SUPPORTED)上使用onMessage()表示并将数据库工作移动到@TransactionAttribute(REQUIRES_NEW)

的另一个bean

请注意单独的方法方法,因为这不起作用。在JMS MDB中,onMessage()方法是唯一可以使用@TransactionAttribute的方法。

答案 1 :(得分:2)

我个人从不在MDB中做任何工作,而是立即向(注入)会话bean发送。

这个bean然后执行数据库工作。它要么启动一个新事务,要么从bean中捕获任何异常并记录它(但不要让它传播,所以没有重新传递)。

这也有一个优点,即业务逻辑可以从其他地方轻松重用。