Exception 如何在camel中的客户端确认模式中捕获异常后防止消息提交

Exception 如何在camel中的客户端确认模式中捕获异常后防止消息提交,exception,apache-camel,Exception,Apache Camel,现在我有了一个监听jms队列的程序,它在程序毫无例外地使用消息之后使用客户机确认模式提交事务 public void process(Exchange exch) throws Exception { JmsMessage message = (JmsMessage) exch.getIn(); try { ... javax.jms.Message msg = message.getJmsMessage();

现在我有了一个监听jms队列的程序,它在程序毫无例外地使用消息之后使用客户机确认模式提交事务

public void process(Exchange exch) throws Exception {
        JmsMessage message = (JmsMessage) exch.getIn();
        try {
            ...
            javax.jms.Message msg = message.getJmsMessage();
            log.info("commit ems level transaction");
            msg.acknowledge();
        } catch (Exception e) {
            ...
        }
    }
我尝试在我的程序上设置断点,当它捕获异常时,如果异常处理代码还没有完成执行,消息仍然存在于队列中,一旦异常处理代码完成执行,消息就会被删除

那么,如何在捕获ecxeption时停止消息提交


谢谢你的帮助~~

如果您使用的是Camel,那么为什么您会通过针对Camel进行编程而弄脏您的手呢?骆驼队免费为你做这一切

只需在不使用外部事务管理器的情况下使用消息消费,Camel就会自动提交成功处理的消息,并回滚带有处理错误的消息messagebroker然后重新传递消息或将消息移动到一个新的位置

此设置的关键是正确配置驼峰JMS组件。因为你可以这样做

@Bean("activemq")
public ActiveMQComponent createActiveMQComponent(final ConnectionFactory connectionFactory) {
    final ActiveMQComponent activeMQComponent = new ActiveMQComponent();
    final JmsConfiguration jmsConfiguration = new JmsConfiguration();
    jmsConfiguration.setConnectionFactory(connectionFactory);
    jmsConfiguration.setLazyCreateTransactionManager(false);
    jmsConfiguration.setTransacted(true);
    jmsConfiguration.setConcurrentConsumers([number of concurrent consumers]);
    jmsConfiguration.setCacheLevelName("CACHE_CONSUMER");
    activeMQComponent.setConfiguration(jmsConfiguration);
    return activeMQComponent;
}
这其中的重要部分是这两种配置

jmsConfiguration.setLazyCreateTransactionManager(false);
jmsConfiguration.setTransacted(true);
此组件配置与未配置Spring事务管理器相结合,为您提供与代理的本地事务

如果完成此设置,您只需编写路由即可使用队列中的消息:

from("activemq:queue:myQueue")
...
您不能在路由中使用Camel transacted语句,因为这与配置的事务管理器相关,不适用于本地JMS事务。但是不要担心,如果上面的设置是正确的,那么您的JMS使用者路由完全可以在不进行事务处理的情况下进行事务处理

您也不需要像示例中那样配置队列。您可以将Camel中的队列端点配置为简单字符串,如我的示例所示

from("activemq:queue:myQueue")
activemq = component name
queue = consume from a queue (not a topic)
myQueue = queue name

如果愿意,还可以使用来处理处理错误。但请确保理解再次发送代理重新交付消息和重复仅骆驼重新交付处理步骤之间的区别。

以前它使用默认的AcknowledgementModelName,现在我必须使用客户端模式来控制何时提交事务,而Camel.Message对我来说没有方法,所以我使用jms.Message进行确认。我发现,即使我设置了客户机模式,它也总是提交事务,无论程序抛出异常或运行良好,即使我没有调用message.acknowledge方法当您使用的事务不是自动确认或客户机确认时,成功的消息会提交,失败的消息不会提交。这是您正在寻找的还是您需要做更多的事情?一旦我从队列中获得消息,我将对其进行分析并将其保存到数据库中。现在我假设数据库关闭了,并且我已经得到了消息,它将抛出sql异常,并且消息已从队列中删除。现在我想要的是,在消息持久化到db之前,不能从队列中删除消息,这听起来正是驼峰事务JMS消费者为您所做的任何网站或示例?谢谢
from("activemq:queue:myQueue")
activemq = component name
queue = consume from a queue (not a topic)
myQueue = queue name