@MessageDriven 事务和重新传递语义
Posted
技术标签:
【中文标题】@MessageDriven 事务和重新传递语义【英文标题】:@MessageDriven transactions and redelivery semantics 【发布时间】:2012-01-31 03:37:01 【问题描述】:完成以下任务的最佳方法是什么?
@MessageDriven bean 在数据库上做了一些工作 失败时,我想回滚数据库事务 但我也希望不要重新传递 JMS 消息,即不要重试。我能想到一些可能起作用的方法。还有其他的吗,哪个最好?
使用@TransactionManagement(type=BEAN)
和UserTransaction
,捕获异常后显式回滚。例如:
catch (Exception e)
e.printStackTrace();
utx.rollback();
使用容器管理的事务,在onMessage
上指定@TransactionAttribute(value=NOT_SUPPORTED)
,然后使用@TransactionAttribute(value=REQUIRED)
将数据库活动委托给单独的方法。
不理会事务处理并重新配置服务器中的重试属性。我正在使用 Glassfish 3.1.1,但我不确定如何设置它。
不理会所有内容,并在 onMessage
正文中明确检查消息是否重新发送,如果重新发送则退出。 (message.getJMSRedelivered()
?)
那里有什么效果很好?是否有处理此问题的标准/最佳实践方法?
【问题讨论】:
【参考方案1】:最简单和最便携的方法是在您声明的onMessage()
上使用@TransactionAttribute(value=NOT_SUPPORTED)
,并使用@TransactionAttribute(REQUIRES_NEW)
将数据库工作移动到另一个bean
注意单独的方法方法,因为这不起作用。在 JMS MDB 中,onMessage()
方法是唯一可以使用@TransactionAttribute
的方法。
【讨论】:
谢谢,这很好用。 MDB 中关于@TransactionAttribute 的注释很关键——你是对的,你只能注释onMessage
。最后我没有注释onMessage
,但确实使用REQUIRES_NEW
将逻辑移动到另一个EJB。
作为注释,它适用于带有“REQUIRED”注释的子 EJB。【参考方案2】:
就我个人而言,我从未在 MDB 中做任何工作,而是立即分派给(注入的)会话 bean。
然后这个 bean 执行 DB 工作。它要么启动一个新事务,要么我从 bean 中捕获任何异常并将其记录下来(但不要让它传播,因此不会重新传递)。
这还有一个好处是业务逻辑很容易从其他地方重用。
【讨论】:
以上是关于@MessageDriven 事务和重新传递语义的主要内容,如果未能解决你的问题,请参考以下文章