【问题标题】:Camel exception/error handling transacted route without causing client exception骆驼异常/错误处理事务路由而不导致客户端异常
【发布时间】:2015-03-03 12:43:38
【问题描述】:

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

  • 我向系统发送请求-回复命令“X”。

  • 系统通过交易骆驼路线接收“X”。

  • 在处理“X”时,系统会发出几个事件,“Y”和“Z”, 但作为交易路线的一部分,这些不应该被刷新 直到交易完成。

  • 发生运行时异常 - 这应该会导致事务 回滚。

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

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

地点:

  • DESTINATION_FOR_EXCEPTION_HANDLING 是一个接受异常并返回消息对象的 bean
  • DESTINATION_FOR_REPLIES 是一个 bean,它将输出正文设置为消息对象

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

  • 防止“Y”和“Z”被刷新 - 好
  • 在发出 requestReply 的客户端上导致交换异常 - BAD

如果我不包括它,那么:

  • “Y”和“Z”被刷新 - 坏
  • 我在客户端收到正版消息对象 - 好

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

【问题讨论】:

    标签: java error-handling apache-camel transactional


    【解决方案1】:

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

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

       <bean id="activemq" ...>
    
       <bean id="activemq2" ...>
    

    然后在onException中使用activemq2。然后可以配置为使用相同的 brokerUrl 和所有这些。第二次您可能需要将其设置为 transacted=false。

    【讨论】:

    • 这是否仍不会导致客户端异常,因为原始组件仍会以交换异常响应?
    【解决方案2】:

    我尝试了克劳斯的方法,但由于某种原因无法使其工作,我一定是误解或设置不正确。

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

        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)...
    

    【讨论】:

      猜你喜欢
      • 2018-08-15
      • 2012-09-09
      • 1970-01-01
      • 2023-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-10
      相关资源
      最近更新 更多