gpt4 book ai didi

java - 在不重试消息的情况下在 MessageDrivenBean 中将事务标记为仅回滚

转载 作者:搜寻专家 更新时间:2023-11-01 03:43:30 25 4
gpt4 key购买 nike

我有以下 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 实体。

我的问题是:如何在不触发消息重新投递的情况下将事务标记为仅回滚?

最佳答案

我看到两个选项:

  1. 使用 @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 注释 bean,使用 bean 管理的事务并且没有 AUTO_ACKNOWLEDGE(在 MDB 中显式确认消息)。如果您的 MDB 是更大的 XA 事务的一部分,则不是一个选项,您将没有机会影响全局事务结果。
  2. 检查消息上的 getJMSRedelivered() 标志并简单地丢弃重新传送的消息。这里的问题是,在重新交付时你不知道它是否是你应该忽略的重新交付(你说在某些情况下你确实想重试处理) - 你必须临时存储(在数据库或缓存中)ids处理失败的邮件数量,因此您知道是否可以安全地忽略它们。

关于java - 在不重试消息的情况下在 MessageDrivenBean 中将事务标记为仅回滚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8761970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com