java – 在MessageDrivenBean中将事务标记为仅回滚,而不重试该消
我有以下MessageDrivenBean:
@MessageDriven(mappedName = "jms/...",activationConfig = { @ActivationConfigProperty(propertyName = "destinationType",propertyValue = "javax.jms.Queue"),@ActivationConfigProperty(propertyName = "endpointExceptionRedeliveryAttempts",propertyValue = "5"),@ActivationConfigProperty(propertyName = "endpointExceptionRedeliveryInterval",propertyValue = "1000") }) public class MyMessageListener implements MessageListener { @Resource private MessageDrivenContext context; @Override @TransactionAttribute(REQUIRED) public void onMessage(Message message) { } } 在onMessage方法中,我做了一些在这里不重要的处理.在某些情况下,我想放弃处理.在那种情况下,我想将事务标记为仅回滚,并且不想重试处理. 至少在Glassfish 3.1.1上,如果我在MessageDrivenContext上调用context.setRollbackOnly()并结束处理而不抛出异常,则会在非常非常短的时间间隔内无限地重新传递消息.所以这对我来说是没有选择的. 如果我抛出RuntimeException,则会根据我的指定重新传递消息.它以1秒的间隔重新传送5次.但就我而言,我根本不想重试处理. 如果我只是结束处理而不抛出任何异常并且不调用context.setRollbackOnly(),那么事务就会被提交,正如人们所期望的那样.但是我需要回滚事务,因为我可能已经改变了一些JPA实体. 我的问题是:如何在不触发消息重新传递的情况下将事务标记为仅回滚? 解决方法
我看到两个选择:
>使用@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)注释bean,使用bean管理的事务,不使用AUTO_ACKNOWLEDGE(在MDB中显式确认消息).如果您的MDB是更大的XA事务的一部分,则不是一个选项,您将没有机会影响全局事务结果.>检查消息上的getJMSRedelivered()标志,然后丢弃重新传递的消息.这里的问题是,在重新传递时你不知道它是否是你应该忽略的重新传递(你说在某些情况下你确实想重试处理) – 你必须暂时存储(在数据库或缓存中)id处理失败的消息,因此您知道是否可以安全地忽略它们. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |