Camel exception/error 处理事务路由而不导致客户端异常

Camel exception/error handling transacted route without causing client exception

我正在使用一个命令事件驱动的系统,使用 JMS 和 Apache Camel 进行路由。在以下情况下:

我希望能够拦截异常并用真正的消息(而不是异常)回复客户端。因此,我开始实施错误处理程序:

    onException(RuntimeException.class)
        .handled(true)
        .markRollbackOnly()
        .filter(header(Header.REPLY_TO.getName()).isNotNull())
        .to(DESTINATION_FOR_EXCEPTION_HANDLING)
        .to(DESTINATION_FOR_REPLIES);

其中:

我遇到的问题是,如果我包含 "markRollbackOnly()" 它:

如果我不包括它,那么:

我如何配置 camel 以防止在事务中刷新消息,同时又能够将异常转换为已处理的错误消息?

如果发送到这两个目的地的 onException 使用与 from 相同的 Camel 组件,那么您将需要为此使用一个单独的组件,以便它们是独立的。因为回滚否则会导致它们全部回滚。

假设您使用 ActiveMQ,您只需声明两个组件

   <bean id="activemq" ...>

   <bean id="activemq2" ...>

然后在onException中使用activemq2。然后可以配置为使用相同的 brokerUrl 等等。对于第二次,您可能需要将其设置为 transacted=false.

我尝试了 Claus 方法,但由于某种原因无法正常工作,我一定是误解了或设置不正确。

最终我通过在内部传播第二个事务解决了这个问题,一个错误处理程序然后我可以 "markRollbackOnlyLast" 第二个事务,但在主事务上用 "good" 消息响应:

    TransactionTemplate newTransactionTemplate = new TransactionTemplate(platformTransactionManager);
    newTransactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
    Policy requireNewTransaction = new SpringTransactionPolicy(newTransactionTemplate);

    onException(RuntimeException.class)
        .onWhen(header(Header.REPLY_TO.getName()).isNotNull())
            .log(LoggingLevel.ERROR, EXCEPTION_STACKTRACE)
            .to(PROCESSOR_FOR_EXCEPTION_HANDLING)
            .to(PROCESSOR_FOR_REPLY)
            .handled(true)
            .markRollbackOnlyLast();

    from(FROM)
        .policy(requireNewTransaction)...